'use strict'

// Minimal reimplementation of babel-plugin-replace-import-extension
// (https://www.npmjs.com/package/babel-plugin-replace-import-extension), which
// is not packaged in Debian. It rewrites the file extension of *relative*
// import / export / require / import() specifiers according to the `extMapping`
// option, e.g. { ".js": ".cjs" } turns
//     import x from "./foo/index.js"
// into
//     import x from "./foo/index.cjs"
//
// date-fns uses it in its CommonJS build (BABEL_ENV=cjs) to map ".js" -> ".cjs"
// so the emitted require() calls point at the sibling .cjs files.

function makeReplacer(extMapping) {
  const entries = Object.entries(extMapping || {})
  return function (source) {
    if (typeof source !== 'string' || source[0] !== '.') return source
    for (const [from, to] of entries) {
      if (source.endsWith(from)) {
        return source.slice(0, source.length - from.length) + to
      }
    }
    return source
  }
}

module.exports = function replaceImportExtension({ types: t }) {
  return {
    name: 'replace-import-extension',
    visitor: {
      'ImportDeclaration|ExportNamedDeclaration|ExportAllDeclaration'(path, state) {
        const source = path.node.source
        if (source && t.isStringLiteral(source)) {
          source.value = makeReplacer(state.opts.extMapping)(source.value)
        }
      },
      CallExpression(path, state) {
        const { callee, arguments: args } = path.node
        const isImport = t.isImport(callee)
        const isRequire = t.isIdentifier(callee, { name: 'require' })
        if ((isImport || isRequire) && args.length > 0 && t.isStringLiteral(args[0])) {
          args[0].value = makeReplacer(state.opts.extMapping)(args[0].value)
        }
      },
    },
  }
}
