import babel from "@babel/core";
import esbuild from "esbuild";
import * as colors from "kleur/colors";
import * as eslexer from "es-module-lexer";
import path from "path";
import {error} from "../core/logger.js";
import {parseNpmName} from "../core/util.js";
const JSX_RENDERER_CACHE = new WeakMap();
const JSX_EXTENSIONS = new Set([".jsx", ".tsx"]);
const IMPORT_STATEMENTS = {
  react: "import React from 'react'",
  preact: "import { h } from 'preact'",
  "solid-js": "import 'solid-js/web'"
};
const PREVENT_UNUSED_IMPORTS = ";;(React,Fragment,h);";
function isSSR(options) {
  if (options === void 0) {
    return false;
  }
  if (typeof options === "boolean") {
    return options;
  }
  if (typeof options == "object") {
    return !!options.ssr;
  }
  return false;
}
function jsx({config, logging}) {
  let viteConfig;
  return {
    name: "@astrojs/vite-plugin-jsx",
    enforce: "pre",
    configResolved(resolvedConfig) {
      viteConfig = resolvedConfig;
    },
    async transform(code, id, ssrOrOptions) {
      const ssr = isSSR(ssrOrOptions);
      if (!JSX_EXTENSIONS.has(path.extname(id))) {
        return null;
      }
      const {mode} = viteConfig;
      let jsxRenderers = JSX_RENDERER_CACHE.get(config);
      if (!jsxRenderers) {
        jsxRenderers = new Map();
        const possibleRenderers = await loadJSXRenderers(config.renderers);
        if (possibleRenderers.size === 0) {
          throw new Error(`${colors.yellow(id)}
Unable to resolve a renderer that handles JSX transforms! Please include a \`renderer\` plugin which supports JSX in your \`astro.config.mjs\` file.`);
        }
        for (const [importSource2, renderer] of possibleRenderers) {
          jsxRenderers.set(importSource2, renderer);
        }
        JSX_RENDERER_CACHE.set(config, jsxRenderers);
      }
      if (jsxRenderers.size === 1) {
        const {code: jsxCode} = await esbuild.transform(code, {
          loader: getLoader(path.extname(id)),
          jsx: "preserve"
        });
        return transformJSX({code: jsxCode, id, renderer: [...jsxRenderers.values()][0], mode, ssr});
      }
      const {code: jsCode} = await esbuild.transform(code + PREVENT_UNUSED_IMPORTS, {
        loader: getLoader(path.extname(id)),
        jsx: "transform",
        jsxFactory: "h",
        jsxFragment: "Fragment"
      });
      let imports = [];
      if (/import/.test(jsCode)) {
        let [i] = eslexer.parse(jsCode);
        imports = i;
      }
      let importSource;
      if (imports.length > 0) {
        for (let {n: spec} of imports) {
          const pkg = spec && parseNpmName(spec);
          if (!pkg)
            continue;
          if (jsxRenderers.has(pkg.name)) {
            importSource = pkg.name;
            break;
          }
        }
      }
      if (!importSource) {
        const multiline = code.match(/\/\*\*[\S\s]*\*\//gm) || [];
        for (const comment of multiline) {
          const [_, lib] = comment.match(/@jsxImportSource\s*(\S+)/) || [];
          if (lib) {
            importSource = lib;
            break;
          }
        }
      }
      if (importSource) {
        const jsxRenderer = jsxRenderers.get(importSource);
        if (!jsxRenderer) {
          error(logging, "renderer", `${colors.yellow(id)} No renderer installed for ${importSource}. Try adding \`@astrojs/renderer-${importSource}\` to your dependencies.`);
          return null;
        }
        const {code: jsxCode} = await esbuild.transform(code, {
          loader: getLoader(path.extname(id)),
          jsx: "preserve"
        });
        return transformJSX({code: jsxCode, id, renderer: jsxRenderers.get(importSource), mode, ssr});
      }
      const defaultRenderer = [...jsxRenderers.keys()][0];
      error(logging, "renderer", `${colors.yellow(id)}
Unable to resolve a renderer that handles this file! With more than one renderer enabled, you should include an import or use a pragma comment.
Add ${colors.cyan(IMPORT_STATEMENTS[defaultRenderer] || `import '${defaultRenderer}';`)} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file.
`);
      return null;
    }
  };
}
function getLoader(fileExt) {
  return fileExt.substr(1);
}
async function loadJSXRenderers(rendererNames) {
  const renderers = new Map();
  await Promise.all(rendererNames.map((name) => import(name).then(({default: renderer}) => {
    if (!renderer.jsxImportSource)
      return;
    renderers.set(renderer.jsxImportSource, renderer);
  })));
  return renderers;
}
async function transformJSX({code, mode, id, ssr, renderer}) {
  const {jsxTransformOptions} = renderer;
  const options = await jsxTransformOptions({mode, ssr});
  const result = await new Promise((resolve, reject) => {
    const plugins = [...options.plugins || []];
    babel.transform(code, {
      presets: options.presets,
      plugins,
      cwd: process.cwd(),
      filename: id,
      ast: false,
      compact: false,
      sourceMaps: true,
      configFile: false,
      babelrc: false
    }, (err, res) => {
      if (err) {
        reject(err);
      } else {
        return resolve(res);
      }
    });
  });
  if (!result)
    return null;
  return {
    code: result.code || "",
    map: result.map
  };
}
export {
  jsx as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3ZpdGUtcGx1Z2luLWpzeC9pbmRleC50cyJdLAogICJtYXBwaW5ncyI6ICJBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTSxxQkFBcUIsSUFBSTtBQUMvQixNQUFNLGlCQUFpQixJQUFJLElBQUksQ0FBQyxRQUFRO0FBQ3hDLE1BQU0sb0JBQTRDO0FBQUEsRUFDaEQsT0FBTztBQUFBLEVBQ1AsUUFBUTtBQUFBLEVBQ1IsWUFBWTtBQUFBO0FBSWQsTUFBTSx5QkFBeUI7QUFHL0IsZUFBZSxTQUEwRDtBQUN2RSxNQUFJLFlBQVksUUFBVztBQUN6QixXQUFPO0FBQUE7QUFFVCxNQUFJLE9BQU8sWUFBWSxXQUFXO0FBQ2hDLFdBQU87QUFBQTtBQUVULE1BQUksT0FBTyxXQUFXLFVBQVU7QUFDOUIsV0FBTyxDQUFDLENBQUMsUUFBUTtBQUFBO0FBRW5CLFNBQU87QUFBQTtBQVNNLGFBQWEsQ0FBRSxRQUFRLFVBQTBDO0FBQzlFLE1BQUk7QUFFSixTQUFPO0FBQUEsSUFDTCxNQUFNO0FBQUEsSUFDTixTQUFTO0FBQUEsSUFDVCxlQUFlLGdCQUFnQjtBQUM3QixtQkFBYTtBQUFBO0FBQUEsVUFFVCxVQUFVLE1BQU0sSUFBSSxjQUFjO0FBQ3RDLFlBQU0sTUFBTSxNQUFNO0FBQ2xCLFVBQUksQ0FBQyxlQUFlLElBQUksS0FBSyxRQUFRLE1BQU07QUFDekMsZUFBTztBQUFBO0FBR1QsWUFBTSxDQUFFLFFBQVM7QUFDakIsVUFBSSxlQUFlLG1CQUFtQixJQUFJO0FBRzFDLFVBQUksQ0FBQyxjQUFjO0FBQ2pCLHVCQUFlLElBQUk7QUFDbkIsY0FBTSxvQkFBb0IsTUFBTSxpQkFBaUIsT0FBTztBQUN4RCxZQUFJLGtCQUFrQixTQUFTLEdBQUc7QUFFaEMsZ0JBQU0sSUFBSSxNQUNSLEdBQUcsT0FBTyxPQUNSO0FBQUE7QUFBQTtBQUlOLG1CQUFXLENBQUMsZUFBYyxhQUFhLG1CQUFtQjtBQUN4RCx1QkFBYSxJ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
