"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bundle = bundle;
exports.bundle_ = bundle_;
exports.defaultBundle = defaultBundle;
const esbuild_1 = require("esbuild");
const fs_extra_1 = require("fs-extra");
const promises_1 = require("fs/promises");
const path = __importStar(require("path"));
const path_1 = require("../path");
const sync_1 = require("../script/sync");
const collectIdSet_1 = require("./collectIdSet");
const constants_1 = require("./constants");
async function bundle(unitPath, projectPath, outputFolder, includeSystem, opt) {
    const bundlePath = path.join(projectPath, 'bundle.json');
    const bootPath = path.join(projectPath, 'system.json');
    await bundle_(unitPath, bundlePath, bootPath, outputFolder, includeSystem, opt);
}
async function bundle_(unitPath, bundlePath, bootPath, outputFolder, includeSystem, opt) {
    const systemPath = path.join(unitPath, 'src', 'system');
    const entrypoint = path.join(unitPath, 'src/client/platform/web/index.ts');
    const fallbackBootPath = path.join(unitPath, 'src/client/platform/web/system.json');
    const outputPath = path.join(outputFolder, 'index.js');
    const bootPathExists = await (0, fs_extra_1.pathExists)(bootPath);
    const bundle = await (0, fs_extra_1.readJSON)(bundlePath);
    const set = includeSystem ? undefined : (0, collectIdSet_1.collectIdSetFromBundle)(bundle);
    await (0, sync_1.sync)(systemPath, outputFolder, set);
    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 === './system.json') {
                        if (bootPathExists) {
                            return { path: bootPath };
                        }
                        else {
                            return { path: fallbackBootPath };
                        }
                    }
                }
                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 };
                }
                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(systemPath, '')
                        .replace('.ts', '');
                    const otherPath = path.join(outputFolder, `${absolutePath}.ts`);
                    return { path: otherPath };
                }
                return {};
            });
        },
    };
    const esbuildOptions = {
        ...constants_1.DEFAULT_BUILD_OPTIONS,
        entryPoints: [entrypoint],
        plugins: [resolvePlugin],
        outfile: outputPath,
        ...opt,
    };
    await (0, esbuild_1.build)(esbuildOptions);
    await (0, promises_1.unlink)(path.join(outputFolder, '_specs.ts'));
    await (0, promises_1.unlink)(path.join(outputFolder, '_ids.ts'));
    await (0, promises_1.unlink)(path.join(outputFolder, '_classes.ts'));
    await (0, promises_1.unlink)(path.join(outputFolder, '_components.ts'));
}
async function defaultBundle(bundlePath, bootPath, outputFolder, includeSystem, opt) {
    const unitPath = path_1.PATH_UNIT;
    return bundle_(unitPath, bundlePath, bootPath, outputFolder, includeSystem, opt);
}
//# sourceMappingURL=bundle.js.map