"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildH5App = void 0;
const path_1 = __importDefault(require("path"));
const weapps_core_1 = require("@cloudbase/lowcode-generator/lib/weapps-core");
const material_1 = require("./material");
const generate_1 = require("./generate");
const webpack_1 = require("./webpack");
const webpack_2 = require("../service/webpack");
const npm_1 = require("./npm");
const copy_1 = require("./copy");
const common_1 = require("../types/common");
const compile_1 = require("./compile");
const util_1 = require("../util");
const types_1 = require("../../types");
const mp_1 = require("../mp");
const common_2 = require("../../utils/common");
const config_1 = require("../config");
const fs_extra_1 = __importDefault(require("fs-extra"));
async function buildH5App({ buildContext, i18nConfig, extraData, cals, buildTypeList = [common_1.BuildType.WEB], subAppCalsList, mode, devTool, runtime = types_1.RUNTIME.NONE, deployMode = types_1.DEPLOY_MODE.PREVIEW, ignoreInstall = false, cdnEndpoints, }) {
    var _a, _b, _c;
    const { projDir: buildDir, domain, materialLibs: dependencies, appId: appKey, isPrivateMode } = buildContext;
    try {
        const { materialsDir } = runtime === types_1.RUNTIME.CI ? (0, util_1.getCompileDirs)(appKey) : (0, util_1.getCompileDirs)('app');
        const h5BuildDir = path_1.default.join(buildDir, 'h5');
        if (buildTypeList.includes(common_1.BuildType.APP) ||
            buildTypeList.includes(common_1.BuildType.XPAGE_PC) ||
            buildTypeList.includes(common_1.BuildType.ADMIN_PORTAL)) {
            if (!cals.extra) {
                cals.extra = {};
            }
            cals.extra.historyType = types_1.HISTORY_TYPE.HASH;
        }
        const mainAppSerializeData = (0, common_2.processCals2WeappsData)(cals, dependencies);
        const subAppSerializeDataList = (subAppCalsList === null || subAppCalsList === void 0 ? void 0 : subAppCalsList.map((item) => (0, common_2.processCals2WeappsData)(item, dependencies))) || [];
        const { allAppUsedComps } = (0, mp_1.handleUsedComponents)({
            buildContext: { ...buildContext, mainAppData: mainAppSerializeData },
            weapps: [mainAppSerializeData, ...subAppSerializeDataList],
        });
        // 处理应用数据
        const mainAppData = (0, weapps_core_1.deserialize)(mainAppSerializeData);
        if (!mainAppData.extra) {
            mainAppData.extra = { domain };
        }
        if (!((_a = mainAppData.extra) === null || _a === void 0 ? void 0 : _a.domain)) {
            mainAppData.extra.domain = domain;
        }
        const subAppDataList = subAppSerializeDataList.map((sub) => (0, weapps_core_1.deserialize)(sub));
        // 前置操作
        const { publicPath, basename, assets = '', _indexPage } = ((_b = mainAppData.appConfig) === null || _b === void 0 ? void 0 : _b.window) || {};
        // 获取 插入的cdn 资源
        const jsAssets = await (0, generate_1.handleAssets)({
            appBuildDir: buildDir,
            buildTypeList,
            assets,
        });
        await (0, copy_1.runCopy)(h5BuildDir, mainAppData, i18nConfig);
        // 构建 APP 需要的配置文件
        const appConfig = await (0, webpack_2.generateAppConfig)(mainAppData, subAppDataList, h5BuildDir);
        // // 素材库
        const runHandleMaterialTag = '🚥  buildWebApp-runHandleMaterial';
        console.time(runHandleMaterialTag);
        // 精简只使用用到的组件库，并获取补齐json格式
        const processedDependiencies = await (0, material_1.runHandleMaterial)(h5BuildDir, dependencies.filter((lib) => {
            // 注意需要包涵官方的(gsd)，部分平台方法需要由其补充
            return lib.name === config_1.OFFICIAL_LIB_KEY || !!allAppUsedComps[lib.name];
        }), materialsDir, runtime, ignoreInstall);
        console.timeEnd(runHandleMaterialTag);
        // // 获取 generate 需要的构建文件
        const runGenerateTag = '🚥  buildWebApp-generateProjectFiles';
        console.time(runGenerateTag);
        await (0, generate_1.generateProjectFiles)({
            dependencies: processedDependiencies,
            cals,
            mainAppData,
            subAppDataList,
            appKey,
            publicPath,
            i18nConfig,
            extraData,
            basename,
            appBuildDir: h5BuildDir,
            buildTypeList,
            isSandbox: false,
            runtime,
            deployMode,
            _indexPage,
            isPrivateMode,
        });
        console.timeEnd(runGenerateTag);
        // // 构建 NPM 包
        await (0, npm_1.handleNPM)({
            appKey,
            mainAppData,
            subAppDataList,
            appBuildDir: h5BuildDir,
            dependencies: processedDependiencies,
            mode,
            devTool,
            ignoreInstall,
        });
        // 生成主题文件
        await (0, generate_1.generateThemeVarsFile)(mainAppData.themeVars, h5BuildDir);
        // 生成 webpack 配置
        const webpackConfigPath = await (0, webpack_1.runWebpackCore)({
            appKey,
            mainAppData,
            subAppDataList,
            appBuildDir: h5BuildDir,
            assets: jsAssets,
            buildTypeList,
            mpConfig: appConfig,
            mode,
            devTool,
            publicPath,
            domain,
            cdnEndpoints,
        });
        await new Promise((resolve, reject) => {
            // 开始编译前清理一下 lowcode 内容
            (0, compile_1.startCompile)({
                appBuildDir: h5BuildDir,
                configPath: webpackConfigPath,
                appKey,
                webpackMode: mode,
            }, function (err, data) {
                if (err) {
                    reject(err);
                }
                else {
                    resolve(data);
                }
            });
        });
        // 普通 web 模式，且非hash模式，根据页面生成多份入口
        if (!((_c = cals.extra) === null || _c === void 0 ? void 0 : _c.historyType) || cals.extra.historyType === types_1.HISTORY_TYPE.BROWSER) {
            await Promise.all((cals.items || []).map((page) => fs_extra_1.default.copy(path_1.default.resolve(h5BuildDir, webpack_2.OUTPUT_DIR, 'index.html'), path_1.default.resolve(h5BuildDir, webpack_2.OUTPUT_DIR, page.id, 'index.html'))));
        }
        return h5BuildDir;
    }
    catch (e) {
        // console.error('构建失败：', e);
        throw e;
    }
}
exports.buildH5App = buildH5App;
