"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExportMiniProgramAssetsPlugin = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
const paths_1 = require("@ngtools/webpack/src/ivy/paths");
const system_1 = require("@ngtools/webpack/src/ivy/system");
const path = __importStar(require("path"));
const static_injector_1 = require("static-injector");
const webpack_1 = require("webpack");
const util_1 = require("../../util");
const const_1 = require("../const");
const mini_program_application_analysis_service_1 = require("../mini-program-application-analysis.service");
const token_1 = require("../token");
const util_2 = require("../util");
const i0 = __importStar(require("static-injector"));
const i1 = __importStar(require("../../platform/platform"));
const i2 = __importStar(require("../library-template-scope.service"));
class ExportMiniProgramAssetsPlugin {
    constructor(tsConfig, buildPlatform, injector, libraryTemplateScopeService) {
        this.buildPlatform = buildPlatform;
        this.injector = injector;
        this.libraryTemplateScopeService = libraryTemplateScopeService;
    }
    apply(compiler) {
        const ifs = compiler.inputFileSystem;
        let oldBuilder = undefined;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const styleAssets = new Map();
        compiler.hooks.compilation.tap('ExportMiniProgramAssetsPlugin', (compilation) => {
            compilation.hooks.processAssets.tap('ExportMiniProgramAssetsPlugin', () => {
                for (const stylePath in compilation.assets) {
                    if (Object.prototype.hasOwnProperty.call(compilation.assets, stylePath)) {
                        const data = compilation.getAsset(stylePath);
                        if (/\.(scss|css|sass|less|styl)$/.test(stylePath)) {
                            styleAssets.set(path.normalize(stylePath), data.source);
                            (0, util_2.setCompilationAsset)(compilation, stylePath, new webpack_1.sources.RawSource(' '));
                        }
                    }
                }
            });
        });
        compiler.hooks.thisCompilation.tap('ExportMiniProgramAssetsPlugin', (compilation) => {
            this.system = (0, system_1.createWebpackSystem)(compiler.inputFileSystem, (0, paths_1.normalizePath)(compiler.context));
            this.libraryTemplateScopeService.register(compilation);
            compilation[const_1.InjectorSymbol] = this.injector;
            const injector = static_injector_1.Injector.create({
                providers: [
                    { provide: mini_program_application_analysis_service_1.MiniProgramApplicationAnalysisService },
                    { provide: token_1.WEBPACK_COMPILATION, useValue: compilation },
                    { provide: token_1.WEBPACK_COMPILER, useValue: compiler },
                    { provide: token_1.OLD_BUILDER, useValue: oldBuilder },
                    {
                        provide: token_1.TS_SYSTEM,
                        useValue: this.system,
                    },
                    {
                        provide: token_1.PAGE_PATTERN_TOKEN,
                        useValue: [...this.pageList, ...this.componentList],
                    },
                ],
                parent: this.injector,
            });
            const templateService = injector.get(mini_program_application_analysis_service_1.MiniProgramApplicationAnalysisService);
            oldBuilder =
                templateService.getBuilder();
            const buildTemplatePromise = this.buildTemplate(templateService);
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            compilation[const_1.ExportMiniProgramAssetsPluginSymbol] = {
                buildPlatform: this.buildPlatform,
                otherMetaGroupPromise: buildTemplatePromise.then((item) => item.otherMetaCollectionGroup),
            };
            compilation.hooks.processAssets.tapAsync('ExportMiniProgramAssetsPlugin', (assets, cb) => __awaiter(this, void 0, void 0, function* () {
                const metaMap = yield buildTemplatePromise;
                metaMap.outputContent.forEach((value, key) => {
                    (0, util_2.setCompilationAsset)(compilation, key, new webpack_1.sources.RawSource(value));
                });
                metaMap.style.forEach((value, outputPath) => {
                    (0, util_2.setCompilationAsset)(compilation, outputPath, new webpack_1.sources.ConcatSource(...value.map((item) => styleAssets.get(item))));
                });
                metaMap.config.forEach((value, key) => {
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    let config;
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    if (ifs.fileSystem.existsSync(value.existConfig)) {
                        config = JSON.parse(ifs.readFileSync(value.existConfig).toString());
                    }
                    else {
                        config = {};
                    }
                    config.usingComponents = config.usingComponents || {};
                    config.usingComponents = Object.assign(Object.assign({}, config.usingComponents), value.usingComponents.reduce((pre, cur) => {
                        pre[cur.selector] = cur.path;
                        return pre;
                    }, {}));
                    (0, util_2.setCompilationAsset)(compilation, key, new webpack_1.sources.RawSource(JSON.stringify(config)));
                });
                for (const key in metaMap.otherMetaCollectionGroup) {
                    if (Object.prototype.hasOwnProperty.call(metaMap.otherMetaCollectionGroup, key)) {
                        const element = metaMap.otherMetaCollectionGroup[key];
                        this.libraryTemplateScopeService.setScopeExtraUseComponents(key, {
                            useComponents: Object.assign({}, [...element.localPath, ...element.libraryPath].reduce((pre, cur) => {
                                pre[cur.selector] = cur.path;
                                return pre;
                            }, {})),
                            templateList: element.templateList.map((item) => item.content),
                        });
                    }
                }
                const componentConfigGroup = this.libraryTemplateScopeService.exportLibraryComponentConfig();
                for (const item of componentConfigGroup) {
                    (0, util_2.setCompilationAsset)(compilation, item.filePath, new webpack_1.sources.RawSource(JSON.stringify(item.content)));
                }
                const templateGroup = this.libraryTemplateScopeService.exportLibraryTemplate();
                for (const key in templateGroup) {
                    if (Object.prototype.hasOwnProperty.call(templateGroup, key)) {
                        const element = templateGroup[key];
                        (0, util_2.setCompilationAsset)(compilation, key, new webpack_1.sources.RawSource((0, util_1.literalResolve)(`\`${element}\``, {
                            directivePrefix: this.buildPlatform.templateTransform.getData()
                                .directivePrefix,
                            eventListConvert: this.buildPlatform.templateTransform.eventListConvert,
                            templateInterpolation: this.buildPlatform.templateTransform
                                .templateInterpolation,
                            fileExtname: this.buildPlatform.fileExtname,
                        })));
                    }
                }
                for (const key in metaMap.selfTemplate) {
                    if (Object.prototype.hasOwnProperty.call(metaMap.selfTemplate, key)) {
                        const element = metaMap.selfTemplate[key];
                        (0, util_2.setCompilationAsset)(compilation, key, new webpack_1.sources.RawSource(element));
                    }
                }
                cb();
            }));
            templateService.cleanDependencyFileCache();
        });
    }
    setEntry(pageList, componentList) {
        this.pageList = pageList;
        this.componentList = componentList;
    }
    buildTemplate(service) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield service.analyzeAsync();
                const result = yield service.exportComponentBuildMetaMap();
                return result;
            }
            catch (error) {
                console.error(error);
                throw error;
            }
        });
    }
}
exports.ExportMiniProgramAssetsPlugin = ExportMiniProgramAssetsPlugin;
ExportMiniProgramAssetsPlugin.ɵfac = function ExportMiniProgramAssetsPlugin_Factory(t) { return new (t || ExportMiniProgramAssetsPlugin)(i0.ɵɵinject(token_1.TS_CONFIG_TOKEN), i0.ɵɵinject(i1.BuildPlatform), i0.ɵɵinject(i0.Injector), i0.ɵɵinject(i2.LibraryTemplateScopeService)); };
ExportMiniProgramAssetsPlugin.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: ExportMiniProgramAssetsPlugin, factory: ExportMiniProgramAssetsPlugin.ɵfac });
