import * as ESBuild from "https://deno.land/x/esbuild@v0.19.2/wasm.js";
import * as Mapper from "https://esm.sh/esbuild-plugin-importmaps@1.0.0"; // https://github.com/andstellar/esbuild-plugin-importmaps
import Introspect from "./introspect.ts";

const prefix = "/_dot_importer_/";
const resolvePlugin =(fullPathDir:string):ESBuild.Plugin=>({
  name: "resolve-plugin",
  setup(build) {
    build.onResolve({ filter: /^(\.\/|\.\.\/).*/ }, (args)=>
    {
      let resolveRoot = args.importer||fullPathDir;
      if(resolveRoot.startsWith(prefix))
      {
        resolveRoot = resolveRoot.substring(prefix.length);
      }
      const output:ESBuild.OnResolveResult = {
        path:prefix + new URL(args.path, resolveRoot).href,
        namespace:"http",
      }
      return output;
    });
    build.onLoad({ filter: /.*/, namespace:"http" }, async(args)=> {
      const fetchPath = args.path.substring(prefix.length);
      console.log("fetch path", fetchPath);
      const result = await fetch(fetchPath);
      const contents = await result.text();
      return { contents, loader: `tsx` };
    });
  },
});

await ESBuild.initialize({ worker: false });
export type ImportMap = Parameters<typeof Mapper.importmapPlugin>[0];
export type BuildOptions = ESBuild.BuildOptions;
/**
 * 
 * @param directory Full file:// or http(s):// path to the directory containing assets you want to build (needed to resolve relative imports)
 * @param buildOptions ESBuild "build" options (will be merged with "reasonable defaults") for docs: https://esbuild.github.io/api/#general-options
 * @param importMap An object to act as the import map ({imports:Record<string, string>}). If this is left blank, a configuration will be scanned for in the "directory"
 * @returns build result
 */
export default async function(directory:string, buildOptions={} as BuildOptions, importMap?:ImportMap):Promise<ESBuild.BuildResult<ESBuild.BuildOptions>>
{
  if(!importMap)
  {
    importMap = await Introspect(directory) as ImportMap
  }
  console.log("using import map", importMap);
  const configuration:ESBuild.BuildOptions = {
    entryPoints: ["entry"],
    bundle: true,
    minify: true,
    format: "esm",
    jsx: "automatic",
    jsxImportSource: "react",
    ...buildOptions,
    plugins: [
      resolvePlugin(directory),
      Mapper.importmapPlugin(importMap) as ESBuild.Plugin,
      ...buildOptions.plugins||[]
    ]
  };

  const result = await ESBuild.build(configuration);
  return result;
}
export { ESBuild };