'use strict';

var fs = require('fs');
var path = require('path');
var esbuild = require('esbuild');
var pluginutils = require('@rollup/pluginutils');
var JoyCon = require('joycon');
var jsoncParser = require('jsonc-parser');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var JoyCon__default = /*#__PURE__*/_interopDefaultLegacy(JoyCon);

const joycon = new JoyCon__default['default']();
joycon.addLoader({
  test: /\.json$/,
  load: async (file) => {
    const content = await fs__default['default'].promises.readFile(file, "utf8");
    return jsoncParser.parse(content);
  }
});
const getOptions = async (cwd, tsconfig) => {
  const {data, path} = await joycon.load([tsconfig || "tsconfig.json"], cwd);
  if (path && data) {
    const {jsxFactory, jsxFragmentFactory, target} = data.compilerOptions || {};
    return {
      jsxFactory,
      jsxFragment: jsxFragmentFactory,
      target: target && target.toLowerCase()
    };
  }
  return {};
};

const defaultLoaders = {
  ".js": "js",
  ".jsx": "jsx",
  ".ts": "ts",
  ".tsx": "tsx"
};
var index = (options = {}) => {
  let target;
  const loaders = {
    ...defaultLoaders
  };
  if (options.loaders) {
    for (const key of Object.keys(options.loaders)) {
      const value = options.loaders[key];
      if (typeof value === "string") {
        loaders[key] = value;
      } else if (value === false) {
        delete loaders[key];
      }
    }
  }
  const extensions = Object.keys(loaders);
  const INCLUDE_REGEXP = new RegExp(`\\.(${extensions.map((ext) => ext.slice(1)).join("|")})$`);
  const EXCLUDE_REGEXP = /node_modules/;
  const filter = pluginutils.createFilter(options.include || INCLUDE_REGEXP, options.exclude || EXCLUDE_REGEXP);
  const resolveFile = (resolved, index = false) => {
    for (const ext of extensions) {
      const file = index ? path.join(resolved, `index${ext}`) : `${resolved}${ext}`;
      if (fs.existsSync(file))
        return file;
    }
    return null;
  };
  return {
    name: "esbuild",
    resolveId(importee, importer) {
      if (importer && importee[0] === ".") {
        const resolved = path.resolve(importer ? path.dirname(importer) : process.cwd(), importee);
        let file = resolveFile(resolved);
        if (file)
          return file;
        if (!file && fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
          file = resolveFile(resolved, true);
          if (file)
            return file;
        }
      }
    },
    async transform(code, id) {
      if (!filter(id)) {
        return null;
      }
      const ext = path.extname(id);
      const loader = loaders[ext];
      if (!loader) {
        return null;
      }
      const defaultOptions = options.tsconfig === false ? {} : await getOptions(path.dirname(id), options.tsconfig);
      target = options.target || defaultOptions.target || "es2017";
      const result = await esbuild.transform(code, {
        loader,
        target,
        jsxFactory: options.jsxFactory || defaultOptions.jsxFactory,
        jsxFragment: options.jsxFragment || defaultOptions.jsxFragment,
        define: options.define,
        sourcemap: options.sourceMap !== false,
        sourcefile: id
      });
      printWarnings(id, result, this);
      return result.code && {
        code: result.code,
        map: result.map || null
      };
    },
    async renderChunk(code) {
      if (options.minify) {
        const result = await esbuild.transform(code, {
          loader: "js",
          minify: true,
          target
        });
        if (result.code) {
          return {
            code: result.code,
            map: result.map || null
          };
        }
      }
      return null;
    }
  };
};
function printWarnings(id, result, plugin) {
  if (result.warnings) {
    for (const warning of result.warnings) {
      let message = `[esbuild]`;
      if (warning.location) {
        message += ` (${path.relative(process.cwd(), id)}:${warning.location.line}:${warning.location.column})`;
      }
      message += ` ${warning.text}`;
      plugin.warn(message);
    }
  }
}

module.exports = index;
