import { readFileSync, writeFileSync } from "node:fs";
import { telemetry } from "../events/index.js";
import { eventAppToggled } from "../events/toolbar.js";
const VIRTUAL_MODULE_ID = "astro:toolbar:internal";
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
function astroDevToolbar({ settings, logger }) {
  let telemetryTimeout;
  return {
    name: "astro:dev-toolbar",
    config() {
      return {
        optimizeDeps: {
          // Optimize CJS dependencies used by the dev toolbar
          include: [
            "astro > aria-query",
            "astro > axobject-query",
            ...settings.devToolbarApps.length > 0 ? ["astro/toolbar"] : []
          ],
          esbuildOptions: {
            plugins: [
              {
                name: "astro:strip-toolbar-sourcemap",
                setup(build) {
                  build.onEnd((result) => {
                    if (!result.metafile) return;
                    for (const outputPath of Object.keys(result.metafile.outputs)) {
                      if (!outputPath.includes("entrypoint") || !outputPath.endsWith(".js"))
                        continue;
                      const code = readFileSync(outputPath, "utf-8");
                      const stripped = code.replace(/\/\/# sourceMappingURL=.*$/m, "");
                      if (stripped !== code) {
                        writeFileSync(outputPath, stripped);
                      }
                    }
                  });
                }
              }
            ]
          }
        }
      };
    },
    resolveId: {
      filter: {
        id: new RegExp(`^${VIRTUAL_MODULE_ID}$`)
      },
      handler() {
        return RESOLVED_VIRTUAL_MODULE_ID;
      }
    },
    configureServer(server) {
      server.hot.on("astro:devtoolbar:error:load", (args) => {
        logger.error(
          "toolbar",
          `Failed to load dev toolbar app from ${args.entrypoint}: ${args.error}`
        );
      });
      server.hot.on("astro:devtoolbar:error:init", (args) => {
        logger.error(
          "toolbar",
          `Failed to initialize dev toolbar app ${args.app.name} (${args.app.id}):
${args.error}`
        );
      });
      server.hot.on("astro:devtoolbar:app:toggled", (args) => {
        clearTimeout(telemetryTimeout);
        telemetryTimeout = setTimeout(() => {
          let nameToRecord = args?.app?.id;
          if (!nameToRecord || !nameToRecord.startsWith("astro:")) {
            nameToRecord = "other";
          }
          telemetry.record(
            eventAppToggled({
              appName: nameToRecord
            })
          );
        }, 200);
      });
    },
    load: {
      filter: {
        id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`)
      },
      handler() {
        return {
          code: `
						export const loadDevToolbarApps = async () => {
							return (await Promise.all([${settings.devToolbarApps.map(
            (plugin) => `safeLoadPlugin(${JSON.stringify(
              plugin
            )}, async () => (await import(${JSON.stringify(
              typeof plugin === "string" ? plugin : plugin.entrypoint.toString()
            )})).default, ${JSON.stringify(
              typeof plugin === "string" ? plugin : plugin.entrypoint.toString()
            )})`
          ).join(",")}]));
						};

						async function safeLoadPlugin(appDefinition, importEntrypoint, entrypoint) {
							try {
								let app;
								if (typeof appDefinition === 'string') {
									app = await importEntrypoint();

									if (typeof app !== 'object' || !app.id || !app.name) {
										throw new Error("Apps must default export an object with an id, and a name.");
									}
								} else {
									app = appDefinition;

									if (typeof app !== 'object' || !app.id || !app.name || !app.entrypoint) {
										throw new Error("Apps must be an object with an id, a name and an entrypoint.");
									}

									const loadedApp = await importEntrypoint();

									if (typeof loadedApp !== 'object') {
										throw new Error("App entrypoint must default export an object.");
									}

									app = { ...app, ...loadedApp };
								}

								return app;
							} catch (err) {
								console.error(\`Failed to load dev toolbar app from \${entrypoint}: \${err.message}\`);

								if (import.meta.hot) {
								import.meta.hot.send('astro:devtoolbar:error:load', { entrypoint: entrypoint, error: err.message })
								}

								return undefined;
							}

							return undefined;
						}
					`
        };
      }
    }
  };
}
export {
  astroDevToolbar as default
};
