import { build } from 'esbuild'
import { readFile } from 'fs-extra'
import { buildIdSetFromBundle } from './buildIdSetFromBundle'
import { sync } from './script/sync'
import path = require('path')

export async function buildBundle(
  unitPath: string,
  bundlePath: string,
  outputFolder: string
): Promise<void> {
  const bundleText = await readFile(bundlePath, 'utf8')

  const bundle = JSON.parse(bundleText)

  let idSet = undefined

  idSet = buildIdSetFromBundle(bundle)

  const systemPath = path.join(unitPath, 'src', 'system')

  await sync(systemPath, outputFolder, idSet)

  const entrypoint = `${unitPath}/src/client/platform/web/index.ts`

  const resolvePlugin = {
    name: 'resolve',
    setup(build) {
      build.onResolve({ filter: /.*/ }, (args) => {
        const { resolveDir, importer } = args

        if (importer === entrypoint) {
          if (args.path === './bundle.json') {
            return { path: bundlePath }
          }
        }

        if (
          args.path.endsWith('/system/_specs') ||
          args.path.endsWith('/system/_components') ||
          args.path.endsWith('/system/_ids') ||
          args.path.endsWith('/system/_classes')
        ) {
          const absolutePath = path
            .join(resolveDir, args.path)
            .replace(`${path.join(unitPath, 'src', 'system')}`, '')

          const otherPath = path.join(outputFolder, `${absolutePath}.ts`)

          return { path: otherPath }
        }

        if (importer.endsWith('_classes.ts')) {
          const otherPath = `${path.join(systemPath, args.path, 'index.ts')}`

          return { path: otherPath }
        }

        if (importer.endsWith('_components.ts')) {
          const otherPath = `${path.join(systemPath, args.path)}.ts`

          return { path: otherPath }
        }

        return {}
      })
    },
  }

  await build({
    minify: true,
    sourcemap: false,
    bundle: true,
    logLevel: 'warning',
    entryPoints: [entrypoint],
    define: {
      'globalThis.env': '{"NODE_ENV": "production"}',
    },
    plugins: resolvePlugin ? [resolvePlugin] : [],
    alias: {},
    outfile: `${outputFolder}/index.js`,
  })
}
