'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var node_child_process = require('node:child_process');
var path = require('node:path');
var helper = require('@tarojs/helper');
var constants$1 = require('@tarojs/vite-runner/dist/utils/constants');
var dist = require('@tarojs/plugin-platform-harmony-ets/dist');
var harmony = require('@tarojs/vite-runner/dist/utils/compiler/harmony');
var shared = require('@tarojs/shared');
var core = require('@babel/core');
var page = require('@tarojs/vite-runner/dist/harmony/page');
var utils = require('@tarojs/vite-runner/dist/utils');
var parseCssToStylesheet = require('@tarojs/parse-css-to-stylesheet');
var constants = require('@tarojs/vite-runner/dist/harmony/postcss/constants');

var version = "4.2.0";

const PKG_NAME = '@taro-oh/library';
const PKG_VERSION = version;
const PROJECT_DEPENDENCIES_NAME = [];
const PKG_DEPENDENCIES = {};
const STATIC_FOLDER_NAME = 'static';

/* eslint-disable no-console */
const PLATFORM_NAME = 'harmony_cpp';
const PACKAGE_NAME = '@tarojs/plugin-platform-harmony-cpp';
const NPM_DIR = 'npm';
const CPP_LIBRARY_NAME = 'libTaroHarmonyLibrary.so';
const CPP_LIBRARY_PATH = 'file:./src/main/cpp/types/taro-native-node';
function checkDebug() {
    return process.argv.includes('--debug') || process.argv.includes('-D');
}
function getProcessArg(name, defaultValue = '') {
    const argv = process.argv;
    const index = process.argv.findIndex(arg => arg.startsWith(`--${name}`));
    if (index > -1) {
        if (argv[index].includes('=')) {
            return argv[index].split('=')[1] ?? defaultValue;
        }
        else {
            return argv[index + 1] ?? defaultValue;
        }
    }
    return defaultValue;
}
checkDebug();
function getProjectId(name = '') {
    const pkg = harmony.readJsonSync(path.posix.join(process.cwd(), 'package.json'));
    return `${pkg.name || name}@${pkg.version || '0.0.1'}`;
}
const SEP_RGX = /[\\/]+/g;
function fixBuildProfile(lib = '', outputRoot = '') {
    const stats = helper.fs.statSync(lib);
    if (stats.isDirectory()) {
        helper.fs.readdirSync(lib).forEach((item) => fixBuildProfile(path.join(lib, item), outputRoot));
    }
    else if (stats.isFile() && lib.endsWith('.ets')) {
        let data = helper.fs.readFileSync(lib, 'utf-8');
        const buildProfilePath = path.resolve(outputRoot, 'BuildProfile');
        const rgx = /import\s+(\S+)\s+from\s*['"]BuildProfile['"]/;
        if (rgx.test(data)) {
            data = data.replace(rgx, (_, p1) => {
                return `import ${p1} from '${path.relative(path.dirname(lib), buildProfilePath).replace(SEP_RGX, '/')}'`;
            });
            helper.fs.writeFileSync(lib, data, 'utf-8');
        }
    }
}
function updateBuildProfile(buildProfilePath, hapName = 'entry') {
    if (!helper.fs.existsSync(buildProfilePath)) {
        console.log(helper.chalk.yellow(`目标路径配置文件缺失，可能是非法的 Harmony 模块: ${buildProfilePath}`));
    }
    try {
        const profile = harmony.readJsonSync(buildProfilePath);
        profile.buildOption.externalNativeOptions = {
            ...profile.externalNativeOptions,
            path: './src/main/cpp/CMakeLists.txt',
            arguments: '-DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=compile=8;link=8',
            cppFlags: '',
            abiFilters: [
                'arm64-v8a'
            ]
        };
        if (profile.buildOptionSet instanceof Array) {
            helper.fs.writeFileSync(path.join(buildProfilePath, '..', 'consumer-rules.txt'), [
                '-keep-property-name',
                '',
                // pages
                'toLocation',
                '',
                // '@tarojs/runtime',
                'designRatio',
                'densityDPI',
                'densityPixels',
                'deviceWidth',
                'deviceHeight',
                'viewportWidth',
                'viewportHeight',
                'safeArea',
                'scaledDensity',
                'orientation',
                'content',
                'selectorList',
            ].join('\n'));
            profile.buildOptionSet.forEach((option) => {
                option.arkOptions ||= {};
                option.arkOptions.obfuscation ||= {};
                option.arkOptions.obfuscation.ruleOptions ||= {};
                option.arkOptions.obfuscation.ruleOptions.files ||= [];
                const obfuscations = [
                    './consumer-rules.txt',
                    './src/main/cpp/types/taro-native-node/obfuscation-rules.txt',
                ];
                if (hapName !== 'entry') {
                    option.arkOptions.obfuscation.ruleOptions.enable = true;
                    option.arkOptions.obfuscation.consumerFiles ||= [];
                    const files = option.arkOptions.obfuscation.consumerFiles;
                    if (!files.includes(obfuscations[0])) {
                        files.push(...obfuscations);
                    }
                }
                else {
                    const files = option.arkOptions.obfuscation.ruleOptions.files;
                    if (!files.includes(obfuscations[0])) {
                        files.push(...obfuscations);
                    }
                }
            });
        }
        helper.fs.writeJSONSync(buildProfilePath, profile, { spaces: 2 });
    }
    catch (error) {
        console.warn(helper.chalk.red('更新鸿蒙配置失败：', error));
    }
}

function appPlugin () {
    const that = this;
    return {
        name: 'taro:vite-harmony-template-app',
        enforce: 'pre',
        async buildStart() {
            const pluginContext = this;
            const { runnerUtils } = that.context;
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = await getViteHarmonyCompilerContext(pluginContext);
            if (compiler) {
                const app = compiler.app;
                app.modifyAppImport = function (importStr, _app) {
                    importStr.splice(-3, 0, 'import { TaroWindowUtil } from "@tarojs/runtime"');
                };
                compiler.loaderMeta ||= {};
                const oddModifyInstantiate = compiler.loaderMeta.modifyInstantiate;
                compiler.loaderMeta.modifyInstantiate = function (code = '', type = '', app) {
                    if (type === 'app') {
                        const codeLines = code.split('\n');
                        const resolverIndex = codeLines.findIndex(line => line.includes('context.resolver'));
                        if (resolverIndex >= 0) {
                            codeLines.splice(resolverIndex + 1, 0, codeLines[resolverIndex].replace(/\S+/, 'TaroWindowUtil.setWindowStage(stage)'));
                            code = codeLines.join('\n');
                        }
                    }
                    compiler.modifyHarmonyConfig(this.appConfig);
                    return shared.isFunction(oddModifyInstantiate) ? oddModifyInstantiate.call(this, code, type, app) : code;
                };
            }
        },
    };
}

function injectEnv () {
    const that = this;
    const packageName = '@tarojs/taro';
    const bindingName = 'Taro';
    const businessId = that.getConfig().defineConstants?.LOCATION_APIKEY?.replace(/^['"]|['"]$/g, '');
    return {
        name: 'taro:vite-add-method-env',
        async transform(code, id) {
            const pluginContext = this;
            const { runnerUtils } = that.context;
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = await getViteHarmonyCompilerContext(pluginContext);
            const exts = Array.from(new Set(compiler?.frameworkExts.concat(helper.SCRIPT_EXT)));
            if (!exts.some(ext => id?.split('?')[0].endsWith(ext))) {
                return;
            }
            let taroName = bindingName;
            let imported = false;
            const methodName = ['getLocation'];
            const result = core.transformSync(code, {
                filename: id,
                plugins: [
                    (babel) => {
                        const { types: t } = babel;
                        return {
                            visitor: {
                                Program: {
                                    enter: (ast) => {
                                        taroName = ast.scope.getBinding(bindingName)
                                            ? ast.scope.generateUid(bindingName)
                                            : bindingName;
                                    }
                                },
                                ImportDeclaration(ast) {
                                    if (ast.node.source.value !== packageName)
                                        return;
                                    imported = true;
                                    ast.node.specifiers.forEach(spec => {
                                        if (t.isImportDefaultSpecifier(spec)) {
                                            taroName = spec.local.name;
                                        }
                                        else if (t.isImportSpecifier(spec)) {
                                            const { imported } = spec;
                                            const propertyName = t.isIdentifier(imported) ? imported.name : imported.value;
                                            if (methodName.includes(propertyName)) {
                                                // Note: 记录当前导入的方法别名
                                                methodName.push(spec.local.name);
                                            }
                                        }
                                    });
                                },
                                CallExpression(path) {
                                    if (!imported)
                                        return;
                                    if (!t.isIdentifier(path.node.callee) || !methodName.includes(path.node.callee.name))
                                        return;
                                    const args = path.node.arguments[0];
                                    if (t.isObjectExpression(args)) {
                                        const hasBusinessId = args.properties.some(prop => !t.isSpreadElement(prop) && t.isIdentifier(prop.key) && prop.key.name === 'businessId');
                                        if (!hasBusinessId) {
                                            if (!businessId) {
                                                console.warn(`Error: 使用定位相关 API(${path.node.callee.name}) 时，需要配置 defineConstants.LOCATION_APIKEY 为 businessId.`);
                                                return;
                                            }
                                            args.properties.push(t.objectProperty(t.identifier('businessId'), t.stringLiteral(businessId)));
                                        }
                                    }
                                },
                                MemberExpression(path) {
                                    if (!imported)
                                        return;
                                    if (t.isIdentifier(path.node.object) && path.node.object.name === taroName) {
                                        if (t.isIdentifier(path.node.property) && methodName.includes(path.node.property.name)) {
                                            const parent = path.findParent(p => p.isCallExpression());
                                            if (parent && t.isCallExpression(parent.node)) {
                                                const args = parent.node.arguments[0];
                                                if (t.isObjectExpression(args)) {
                                                    const hasBusinessId = args.properties.some(prop => !t.isSpreadElement(prop) && t.isIdentifier(prop.key) && prop.key.name === 'businessId');
                                                    if (!hasBusinessId) {
                                                        if (!businessId) {
                                                            console.warn(`Error: 使用定位相关 API(${path.node.property.name}) 时，需要配置 defineConstants.LOCATION_APIKEY 为 businessId.`);
                                                            return;
                                                        }
                                                        args.properties.push(t.objectProperty(t.identifier('businessId'), t.stringLiteral(businessId)));
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        };
                    }
                ],
                sourceType: 'module'
            });
            return {
                code: result?.code || code,
                map: result?.map || null,
            };
        }
    };
}

function pagePlugin () {
    const that = this;
    const projectId = getProjectId();
    function genUniPageId(page) {
        return `${projectId}:${page.originName || page.name}`;
    }
    const name = 'taro:vite-harmony-template-page';
    return {
        name,
        enforce: 'pre',
        options(opt) {
            if (opt.plugins instanceof Array) {
                // Note: CAPI 模式禁用半编译能力
                const idx = opt.plugins.findIndex((e) => e && e.name === 'taro:vite-compile-mode');
                if (idx >= 0) {
                    const compileMode = opt.plugins[idx];
                    compileMode.name = 'taro:vite-capi-compile-mode';
                    delete compileMode.transform;
                    opt.plugins.splice(idx, 1, compileMode);
                }
            }
        },
        async buildStart() {
            const pluginContext = this;
            const { runnerUtils, runOpts } = that.context;
            const isPureComp = (page) => {
                if (page instanceof Array)
                    return false;
                if (runOpts?.options?.args.pure || page.config?.entryOption === false) {
                    page.isPure = true;
                }
                else {
                    page.isPure = false;
                }
                return page.isPure;
            };
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = (await getViteHarmonyCompilerContext(pluginContext));
            const taroConfig = compiler.taroConfig;
            if (compiler?.pages instanceof Array || compiler?.components instanceof Array) {
                compiler.loaderMeta ||= {};
                const oddModifyEntryFile = compiler.loaderMeta.modifyEntryFile;
                compiler.loaderMeta.modifyEntryFile = function (type = '', rawId = '', rawCode = '', page) {
                    if (type === 'page') {
                        const isPure = isPureComp(page);
                        const { creatorLocation, frameworkArgs, importFrameworkStatement } = this.loaderMeta;
                        const isBlended = this.buildConfig.blended || this.buildConfig.isBuildNativeComp;
                        const createFn = isPure
                            ? 'createNativeComponentConfig'
                            : isBlended
                                ? 'createNativePageConfig'
                                : 'createPageConfig';
                        const pageId = genUniPageId(page);
                        const createPageOrComponent = `${createFn}(component, ${isPure || isBlended ? `'${pageId}', ${frameworkArgs}` : `'${pageId}', config`})`;
                        return this.transArr2Str([
                            `import { ${createFn} } from '${creatorLocation}'`,
                            ...(importFrameworkStatement || '').split('\n'),
                            `import component from "${utils.escapePath(rawId)}"`,
                            isBlended ? 'import { initPxTransform } from "@tarojs/taro"' : null,
                            `export const config = ${this.prettyPrintJson(page.config)}`,
                            // FIXME: InitPxTransform放在这里会导致多component相互影响
                            isBlended ? this.getInitPxTransform() : null,
                            page?.config.enableShareTimeline ? 'component.enableShareTimeline = true' : null,
                            page?.config.enableShareAppMessage ? 'component.enableShareAppMessage = true' : null,
                            `export default (config = {}) => ${createPageOrComponent}`,
                        ]);
                    }
                    return shared.isFunction(oddModifyEntryFile) ? oddModifyEntryFile.call(this, type, rawId, rawCode, page) : rawCode;
                };
                const oddModifyInstantiate = compiler.loaderMeta.modifyInstantiate;
                compiler.loaderMeta.modifyInstantiate = function (code = '', type = '', page) {
                    if (type === 'page' && !(page instanceof Array)) {
                        const componentName = page.config?.componentName;
                        if (shared.isString(componentName)) {
                            code = code.replace(/export\sdefault\sstruct\sIndex/, `export struct ${componentName}`);
                        }
                    }
                    return shared.isFunction(oddModifyInstantiate) ? oddModifyInstantiate.call(this, code, type, page) : code;
                };
                const parsePageOrComp = (config) => {
                    if (!isPureComp(config)) {
                        config.entryOption = {};
                    }
                    config.modifyPageImport = function (importStr, page) {
                        function fixPageEntry(meta) {
                            Object.assign(config.entryOption, {
                                routeName: meta.name,
                            });
                            if (shared.isObject(meta.config?.entryOption)) {
                                Object.assign(config.entryOption, meta.config.entryOption);
                            }
                        }
                        if (!isPureComp(page)) {
                            if (page instanceof Array) {
                                page.forEach(fixPageEntry);
                            }
                            else {
                                fixPageEntry(page);
                            }
                        }
                        importStr.unshift('import { navigateBack } from "@tarojs/taro"');
                        importStr.unshift('import oh_window from "@ohos.window"');
                        importStr.unshift('import { TaroXComponent } from "@tarojs/components"');
                        importStr.unshift('import { TaroNativeModule, initStyleSheetConfig, systemContext, WINDOW_STATE } from "@tarojs/runtime"');
                        importStr.unshift('import { NodeContent } from "@ohos.arkui.node"');
                        importStr.unshift('import display from "@ohos.display"');
                        importStr.unshift('import { audio } from "@kit.AudioKit"');
                    };
                    config.modifyRenderState = function (state, page) {
                        const isPure = isPureComp(page);
                        state.push(this.renderState({
                            name: '__layoutSize',
                            type: 'TaroAny',
                            foreach: () => 'null',
                            disabled: !this.buildConfig.isBuildNativeComp && isPure,
                        }, false), this.renderState({
                            name: 'areaChange',
                            type: 'TaroAny',
                            foreach: () => 'null',
                        }, false), this.renderState({
                            name: '__pageName',
                            type: 'TaroAny',
                            foreach: () => 'null',
                            disabled: !this.buildConfig.isBuildNativeComp && isPure,
                        }, this.isTabbarPage), this.renderState({
                            decorator: 'State',
                            name: 'params', // FIXME 考虑后续移除该参数
                            type: 'TaroObject',
                            foreach: () => '{}',
                            disabled: !this.buildConfig.isBuildNativeComp && isPure,
                        }, false), this.renderState({
                            decorator: 'State',
                            name: 'statusBarHeight',
                            type: 'number',
                            foreach: () => 'getSystemInfoSync().statusBarHeight || 0',
                        }, this.isTabbarPage), this.renderState({
                            decorator: 'State',
                            name: 'isHideTitleBar',
                            type: 'boolean',
                            foreach: (_, index) => {
                                if (this.isTabbarPage) {
                                    return this.appConfig.window?.navigationStyle === 'custom'
                                        ? `config${index}.navigationStyle !== 'default'`
                                        : `config${index}.navigationStyle === 'custom'`;
                                }
                                else {
                                    return this.appConfig.window?.navigationStyle === 'custom'
                                        ? `config.navigationStyle !== 'default'`
                                        : `config.navigationStyle === 'custom'`;
                                }
                            },
                        }, this.isTabbarPage), this.renderState({
                            decorator: 'State',
                            name: 'isUseCache',
                            type: 'boolean',
                            foreach: () => 'false',
                            disabled: !this.buildConfig.isBuildNativeComp,
                        }, this.isTabbarPage), this.renderState({
                            name: 'isReported',
                            type: 'boolean',
                            foreach: () => 'false',
                            disabled: !this.buildConfig.isBuildNativeComp,
                        }, this.isTabbarPage), this.renderState({
                            name: 'isShown',
                            type: 'boolean',
                            foreach: () => 'true',
                            disabled: !this.buildConfig.isBuildNativeComp && isPure,
                        }, this.isTabbarPage), this.renderState({
                            name: 'nodeContent',
                            type: 'Content',
                            foreach: () => 'new NodeContent()',
                        }, this.isTabbarPage), this.renderState({
                            decorator: 'State',
                            name: 'isReady',
                            type: 'boolean',
                            foreach: () => 'false',
                        }, this.isTabbarPage), this.renderState({
                            decorator: 'State',
                            name: 'pullDownRatio',
                            type: 'number',
                            foreach: () => '1',
                        }, this.isTabbarPage));
                        if (isPureComp(page)) {
                            state.unshift(this.renderState({
                                decorator: 'State',
                                name: 'currentRouter',
                                type: '(TaroObject | null)',
                                foreach: () => 'null',
                            }, this.isTabbarPage));
                        }
                    };
                    config.modifyPageParams = (_) => {
                        return 'this.params';
                    };
                    config.modifyPageAppear = function (appearStr, page) {
                        const isPure = isPureComp(page);
                        const appearCode = isPure
                            ? [
                                `initEtsBuilder('${genUniPageId(page)}')`,
                                `TaroNativeModule.initStylesheet('${genUniPageId(page)}', styleJson, initStyleSheetConfig(this.params._layout_, this.getNavHeight()))`,
                            ]
                            : [
                                `if (!Current.audioSessionManager) {`,
                                `  const audioManager = audio.getAudioManager()`,
                                `  Current.audioSessionManager = audioManager.getSessionManager()`,
                                `}`,
                                `this.activeAudioSession()`,
                                ...(page instanceof Array ? [
                                    ...page.map(p => `initEtsBuilder('${genUniPageId(p)}')`),
                                    ...page.map((p, i) => `this.__pageName[${i}] = '${p.name}'`),
                                ] : [
                                    `initEtsBuilder('${genUniPageId(page)}')`,
                                    `this.__pageName = '${page.name}'`,
                                ]),
                                'this.__layoutSize = this.params._layout_',
                                `systemContext.windowWidth = ${config.config.windowArea?.width || 'this.params._layout_?.width'}`,
                                `systemContext.windowHeight = ${config.config.windowArea?.height || 'this.params._layout_?.height'}`,
                                ...(page instanceof Array ? [
                                    ...page.map((p, i) => `TaroNativeModule.initStylesheet('${genUniPageId(p)}', styleJson${i}, initStyleSheetConfig({ width: systemContext.windowWidth, height: systemContext.windowHeight}, this.getNavHeight()))`),
                                ] : [
                                    `TaroNativeModule.initStylesheet('${genUniPageId(page)}', styleJson, initStyleSheetConfig({ width: systemContext.windowWidth, height: systemContext.windowHeight}, this.getNavHeight()))`,
                                ]),
                            ];
                        if (!isPure) {
                            appearCode.push('Current.$r = (path: string): Resource => {', '  return $r(path)', '}', 'let currentSplit = false', 'let pendingAreaChange: TaroAny', `const resizeFn = (canSplit: boolean, size: TaroAny, sizeChange: boolean) => {`, `  const _display = display.getDefaultDisplaySync()`, `  const orientation = _display.orientation`, `  const idPortrait = orientation == display.Orientation.PORTRAIT || orientation == display.Orientation.PORTRAIT_INVERTED`, `  const _sysInfo: TaroAny = getSystemInfoSync()`, `  callFn(this.page?.onResize, this, {`, `    size: {`, 
                            // @ts-ignore
                            `      windowWidth: ${config.config.windowArea?.width || 'size?.width'},`, 
                            // @ts-ignore
                            `      windowHeight: ${config.config.windowArea?.height || 'size?.height'},`, `      screenWidth: _sysInfo.screenWidth,`, `      screenHeight: _sysInfo.screenHeight,`, `    },`, `    deviceOrientation: idPortrait ? "portrait" : "landscape",`, `    foldDisplayMode: _sysInfo.foldDisplayMode,`, `    canSplit: canSplit,`, `    reason: sizeChange ? "size" : "statusBar"`, `  })`, `}`, `const avoidAreaChange = (res: TaroAny) => {`, `  const statusHeight: number = px2vp(res.area.topRect.height)`, ...(page instanceof Array
                                ? [
                                    `  this.statusBarHeight = this.statusBarHeight.map(() => statusHeight)`,
                                    `  this.node.forEach((item: TaroAny, i) => {`,
                                    `    if (item?._nid) {`,
                                    `      TaroNativeModule.UpdateEnvRule('${getProjectId()}:' + this.__pageName[i], initStyleSheetConfig({ width: this.__layoutSize.width, height: this.__layoutSize.height}, this.getNavHeight()), item._nid)`,
                                    `    }`,
                                    `  })`
                                ]
                                : [
                                    `  this.statusBarHeight = statusHeight`,
                                    `  TaroNativeModule.UpdateEnvRule('${genUniPageId(page)}', initStyleSheetConfig({ width: this.__layoutSize.width, height: this.__layoutSize.height}, this.getNavHeight()), this.node?._nid)`,
                                ]), `  resizeFn(currentSplit, this.__layoutSize, false)`, `}`, `const windowStage: TaroAny = AppStorage.get(WINDOW_STATE)`, 'this.areaChange = (res: TaroAny) => {', '  if (res.type !== oh_window.AvoidAreaType.TYPE_SYSTEM)  return', '  if (!this.isShown) {', '    pendingAreaChange = () => { avoidAreaChange(res) }', '  } else {', '    avoidAreaChange(res)', '  }', '}', `windowStage.getMainWindowSync().on('avoidAreaChange', this.areaChange)`);
                        }
                        appearCode.push(appearStr);
                        return this.transArr2Str(appearCode.filter(Boolean));
                    };
                    config.modifyPageDisappear = function (_disappearStr) {
                        return this.transArr2Str([
                            `this.handlePageDetach()`,
                            'this.deactivateAudioSession()',
                            'if (this.areaChange) {',
                            '  const windowStage: TaroAny = AppStorage.get(WINDOW_STATE)',
                            `  windowStage.getMainWindowSync().off('avoidAreaChange', this.areaChange)`,
                            '}'
                        ]);
                    };
                    config.modifyPageBuild = function (_, page) {
                        const coreBuildCodeArray = [
                            'Stack() {',
                            ...(this.isTabbarPage
                                ? [
                                    '  if (this.isReady[index]) {',
                                    '    TaroXComponent({ pageId: (this.node[index] as TaroAny)?._nid, data: this.nodeContent[index] })',
                                ]
                                : [
                                    '  if (this.isReady) {',
                                    '    TaroXComponent({ pageId: (this.node as TaroAny)?._nid, data: this.nodeContent })',
                                ]),
                            '  }',
                            '}',
                            '.align(Alignment.TopStart)',
                            '.width("100%")',
                            '.constraintSize({',
                            '  minHeight: "100%",',
                            '})',
                            '.onDetach(this.handlePageDetach)',
                        ];
                        if (!isPureComp(page)) {
                            coreBuildCodeArray.push(this.isTabbarPage
                                ? '.backgroundColor(this.pageBackgroundContentColor[index] || this.pageBackgroundColor[index] || "#FFFFFF")'
                                : '.backgroundColor(this.pageBackgroundContentColor || this.pageBackgroundColor || "#FFFFFF")');
                            if (this.enableRefresh === 1) {
                                coreBuildCodeArray.forEach((code, idx) => coreBuildCodeArray.splice(idx, 1, `${' '.repeat(2)}${code}`));
                                coreBuildCodeArray.unshift('Refresh({', '  refreshing: $$this.isRefreshing,', '  builder: this.customRefreshBuilder()', '}) {');
                                coreBuildCodeArray.push('}', '.pullDownRatio(this.pullDownRatio)', '.onStateChange(bindFn(this.handleRefreshStatus, this))');
                            }
                            coreBuildCodeArray.forEach((code, idx) => coreBuildCodeArray.splice(idx, 1, `${' '.repeat(2)}${code}`));
                            coreBuildCodeArray.unshift('Navigation() {');
                            coreBuildCodeArray.push('}', this.isTabbarPage
                                ? `.backgroundColor(this.pageBackgroundColor[index] || '${this.appConfig?.window?.backgroundColor || '#FFFFFF'}')`
                                : `.backgroundColor(this.pageBackgroundColor || '${this.appConfig?.window?.backgroundColor || '#FFFFFF'}')`, `.height('100%')`, `.width('100%')`, `.title({ builder: this.renderTitle, height: this.getNavHeight() })`, `.titleMode(NavigationTitleMode.Mini)`, this.isTabbarPage ? `.hideTitleBar(this.isHideTitleBar[index])` : `.hideTitleBar(this.isHideTitleBar)`, `.hideBackButton(true)`, 
                            // `.expandSafeArea([SafeAreaType.SYSTEM])`,
                            `.mode(NavigationMode.Stack)`);
                        }
                        if (this.isTabbarPage) {
                            coreBuildCodeArray.forEach((code, idx) => coreBuildCodeArray.splice(idx, 1, `${' '.repeat(6)}${code}`));
                            coreBuildCodeArray.unshift('Tabs({', `  barPosition: this.tabBarPosition !== 'top' ? BarPosition.End : BarPosition.Start,`, '  controller: this.tabBarController,', '  index: this.tabBarCurrentIndex,', '}) {', '  ForEach(this.tabBarList, (item: ITabBarItem, index) => {', '    TabContent() {');
                            coreBuildCodeArray.push(`    }.tabBar(this.renderTabItemBuilder(index, item))`, `  }, (item: ITabBarItem, index) => \`\${item.key || index}\`)`, `}`, `.vertical(false)`, `.barMode(BarMode.Fixed)`, `.barHeight(this.isTabBarShow ? 56 : 0)`, `.animationDuration(this.tabBarAnimationDuration)`, `.onChange((index: number) => {`, `  if (this.tabBarCurrentIndex !== index) {`, `    callFn(this.page?.onHide, this)`, `    this.setTabBarCurrentIndex(index)`, `  }`, `  this.handlePageAppear()`, `  callFn(this.page?.onShow, this)`, `})`, `.backgroundColor(this.tabBarBackgroundColor)`, `.padding({`, `  bottom: px2vp(sysInfo.screenHeight - (sysInfo.safeArea?.bottom || 0)),`, `})`);
                        }
                        return this.transArr2Str(coreBuildCodeArray);
                    };
                    config.modifyPageMethods = function (methods, page$1) {
                        const isPure = isPureComp(page$1);
                        const handlePageAppearMethods = methods.find((item) => item.name === 'handlePageAppear');
                        if (handlePageAppearMethods) {
                            const methodsBodyList = handlePageAppearMethods.body?.split('\n') || [];
                            let insertIndex = methodsBodyList.findIndex((item) => item.startsWith('const params'));
                            if (this.isTabbarPage) {
                                insertIndex = methodsBodyList.findIndex((item) => item.includes('this.node[index] = instance'));
                            }
                            else {
                                insertIndex = methodsBodyList.findIndex((item) => item.includes('this.node = instance'));
                            }
                            if (insertIndex >= 0) {
                                methodsBodyList?.splice(insertIndex + 1, 0, ...[
                                    this.isTabbarPage
                                        ? '    TaroNativeModule.buildTaroNode(this.nodeContent[index], instance._nid)'
                                        : '  TaroNativeModule.buildTaroNode(this.nodeContent, instance._nid)',
                                    this.isTabbarPage ? '    this.isReady[index] = true' : '  this.isReady = true',
                                    isPure ? `  this.currentRouter = Current.router` : null,
                                    isPure ? `  eventCenter.on(this.currentRouter?.getEventName('onResize') || '', this.handlePageResizeEvent)` : null,
                                ].filter(shared.isString));
                                if (taroConfig.isWatch) {
                                    handlePageAppearMethods.body = this.transArr2Str([
                                        'try {',
                                        this.transArr2Str(methodsBodyList, 2),
                                        '} catch (error) {',
                                        `  console.error('[TARO_LOG] page-appear:', error.message + '\\n' + error.stack)`,
                                        '}',
                                    ]);
                                }
                                else {
                                    handlePageAppearMethods.body = this.transArr2Str(methodsBodyList);
                                }
                            }
                        }
                        const disabledMethods = ['onPageShow', 'onPageHide'];
                        if (isPure) {
                            disabledMethods.unshift('getPageState');
                            disabledMethods.push('handleRefreshStatus');
                        }
                        disabledMethods.forEach((name) => {
                            const idx = methods.findIndex((e) => e.name === name);
                            if (idx > -1) {
                                methods.splice(idx, 1);
                            }
                        });
                        methods.unshift({
                            name: 'getNavHeight',
                            body: this.isTabbarPage
                                ? 'return this.isHideTitleBar[this.tabBarCurrentIndex] ? 0 : 48 + this.statusBarHeight[this.tabBarCurrentIndex]'
                                : 'return this.isHideTitleBar ? 0 : 48 + this.statusBarHeight',
                        });
                        methods.push({
                            name: 'handlePageDetach',
                            type: 'arrow',
                            body: this.transArr2Str([
                                this.isTabbarPage ? `if (!this.isReady[this.tabBarCurrentIndex]) return` : `if (!this.isReady) return`,
                                '',
                                this.isTabbarPage ? `this.isReady[this.tabBarCurrentIndex] = false` : `this.isReady = false`,
                                isPure
                                    ? `eventCenter.off(this.currentRouter?.getEventName('onResize'), this.handlePageResizeEvent)`
                                    : null,
                                `callFn(this.page?.onUnload, this)`,
                            ]),
                        });
                        methods.push({
                            name: 'activeAudioSession',
                            type: 'arrow',
                            body: this.transArr2Str([
                                `if (Current.audioSessionManager) {`,
                                `  const manager: audio.AudioSessionManager = Current.audioSessionManager`,
                                `  if (!manager.isAudioSessionActivated()) {`,
                                `    let strategy: audio.AudioSessionStrategy = {`,
                                `      concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_PAUSE_OTHERS`,
                                `    }`,
                                `    manager.activateAudioSession(strategy)`,
                                `  }`,
                                `}`,
                            ]),
                        });
                        methods.push({
                            name: 'deactivateAudioSession',
                            type: 'arrow',
                            body: this.transArr2Str([
                                `if (Current.audioSessionManager) {`,
                                `  const manager: audio.AudioSessionManager = Current.audioSessionManager`,
                                `  if (manager.isAudioSessionActivated()) {`,
                                `    manager.deactivateAudioSession()`,
                                `  }`,
                                `}`,
                            ]),
                        });
                        if (!isPure) {
                            const index = methods.findIndex((e) => e.name === 'renderTitle');
                            methods.splice(index, 1, {
                                name: 'renderTitle',
                                decorators: ['Builder'],
                                body: this.transArr2Str([
                                    `Flex({`,
                                    `  direction: FlexDirection.Row,`,
                                    `  justifyContent: FlexAlign.Start,`,
                                    `  alignItems: ItemAlign.Center,`,
                                    `}) {`,
                                    `${this.transArr2Str(!this.isTabbarPage && !this.buildConfig.isBuildNativeComp
                                        // FIXME 这里 pageStack 更新问题，需要第二次才能显示 Home 按钮
                                        ? [
                                            `if (this.pageStack[0].path !== this.entryPagePath && this.navigationBarHomeBtn && this.pageStack.length === 1) {`,
                                            `    Image($r('app.media.taro_home'))`,
                                            `      .height(convertNumber2VP(40 / 7.5, 'vw'))`,
                                            `      .width(convertNumber2VP(40 / 7.5, 'vw'))`,
                                            `      .margin({ left: convertNumber2VP(40 / 7.5, 'vw'), right: convertNumber2VP(-20 / 7.5, 'vw') })`,
                                            `      .fillColor((this.navigationBarTextStyle || '${this.appConfig.window?.navigationBarTextStyle}') !== 'black' ? Color.White : Color.Black)`,
                                            `      .objectFit(ImageFit.Contain)`,
                                            `      .onClick(() => {`,
                                            `        router.replaceUrl({`,
                                            `          url: this.tabBarList.find(e => e.pagePath === this.entryPagePath) ? '${page.TARO_TABBAR_PAGE_PATH}' : this.entryPagePath,`,
                                            `          params: {`,
                                            `            '$page': this.entryPagePath,`,
                                            `          },`,
                                            `        })`,
                                            `      })`,
                                            `  } else if (this.pageStack.length > 1) {`,
                                            `    Image($r('app.media.taro_arrow_left'))`,
                                            `      .height(convertNumber2VP(40 / 7.5, 'vw'))`,
                                            `      .width(convertNumber2VP(40 / 7.5, 'vw'))`,
                                            `      .margin({ left: convertNumber2VP(40 / 7.5, 'vw'), right: convertNumber2VP(-20 / 7.5, 'vw') })`,
                                            `      .fillColor((this.navigationBarTextStyle || '${this.appConfig.window?.navigationBarTextStyle}') !== 'black' ? Color.White : Color.Black)`,
                                            `      .objectFit(ImageFit.Contain)`,
                                            `      .onClick(() => {`,
                                            `        router.back()`,
                                            `      })`,
                                            `  }`,
                                        ] : [], 2)}`,
                                    `  Text(this.navigationBarTitleText${this.isTabbarPage ? '[this.tabBarCurrentIndex]' : ''} || '${this.appConfig.window?.navigationBarTitleText || ''}')`,
                                    `    .margin({ left: convertNumber2VP(40 / 7.5, 'vw') })`,
                                    `    .fontSize(convertNumber2VP(32 / 7.5, 'vw'))`,
                                    `    .fontColor((this.navigationBarTextStyle${this.isTabbarPage ? '[this.tabBarCurrentIndex]' : ''} || '${this.appConfig.window?.navigationBarTextStyle}') !== 'black' ? Color.White : Color.Black)`,
                                    `  if (this.navigationBarLoading${this.isTabbarPage ? '[this.tabBarCurrentIndex]' : ''}) {`,
                                    `    LoadingProgress()`,
                                    `      .margin({ left: convertNumber2VP(10 / 7.5, 'vw') })`,
                                    `      .height(convertNumber2VP(40 / 7.5, 'vw'))`,
                                    `      .width(convertNumber2VP(40 / 7.5, 'vw'))`,
                                    `      .color((this.navigationBarTextStyle${this.isTabbarPage ? '[this.tabBarCurrentIndex]' : ''} || '${this.appConfig.window?.navigationBarTextStyle}') !== 'black' ? Color.White : Color.Black)`,
                                    `  }`,
                                    `}`,
                                    `.height('100%')`,
                                    `.width('100%')`,
                                    `.backgroundColor(this.navigationBarBackgroundColor${this.isTabbarPage ? '[this.tabBarCurrentIndex]' : ''} || '${this.appConfig.window?.navigationBarBackgroundColor || '#000000'}')`,
                                    `.padding({`,
                                    `  top: px2vp(sysInfo.safeArea?.top || 0),`,
                                    `})`,
                                    `.zIndex(1)`,
                                ]),
                            });
                            if (this.enableRefresh === 1) {
                                methods.push({
                                    name: 'customRefreshBuilder',
                                    decorators: ['Builder'],
                                    body: this.transArr2Str([
                                        'if (config?.backgroundImageUrl) {',
                                        '   Image(config?.backgroundImageUrl)',
                                        '      .objectFit(ImageFit.Contain)',
                                        '      .width(32)',
                                        '      .height(32)',
                                        '} else {',
                                        '    LoadingProgress()',
                                        '      .width(32)',
                                        '      .height(32)',
                                        '}',
                                    ]),
                                });
                                // 禁止页面滚动
                                methods.push({
                                    name: 'disablePullDown',
                                    body: this.transArr2Str(['this.pullDownRatio = 0']),
                                });
                                // 允许页面滚动
                                methods.push({
                                    name: 'enablePullDown',
                                    body: this.transArr2Str([' this.pullDownRatio = 1']),
                                });
                            }
                        }
                        else {
                            methods.push({
                                name: 'handlePageResizeEvent',
                                type: 'arrow',
                                params: ['option: TaroObject'],
                                body: this.transArr2Str([
                                    `TaroNativeModule.UpdateStylesheet('${genUniPageId(page$1)}', styleJson, initStyleSheetConfig(option.size, this.getNavHeight()), this.node?._nid)`
                                ]),
                            });
                        }
                    };
                };
                compiler?.pages?.forEach(parsePageOrComp);
                compiler?.components?.forEach(parsePageOrComp);
            }
        },
    };
}

function renderPlugin () {
    const that = this;
    return {
        name: 'taro:vite-harmony-template-render',
        enforce: 'pre',
        async buildStart() {
            const pluginContext = this;
            const { runnerUtils } = that.context;
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = await getViteHarmonyCompilerContext(pluginContext);
            if (compiler) {
                compiler.extraComponents?.push('WaterFlowView');
                compiler.extraComponents?.push('WaterFlow');
                compiler.extraComponents?.push('List');
                compiler.loaderMeta ||= {};
                compiler.loaderMeta.modifyHarmonyRenderChild = function (list) {
                    const comps = list.filter(item => ![
                        'View', 'Button', 'Text', 'Image', 'Icon', 'Input', 'TextArea', 'Swiper', 'ScrollView', 'ScrollList', 'StickySection',
                        'ListView', 'MovableArea', 'MovableView', 'Picker', 'WaterFlow', 'WaterFlowView', 'List', 'Canvas', 'Process',
                        'Label', 'CheckboxGroup', 'Checkbox', 'RadioGroup', 'Radio', 'Form',
                    ].includes(item.name) && item.type !== 'TaroViewElement');
                    list.splice(0, list.length, ...comps, {
                        name: 'XComponent',
                        type: 'TaroElement',
                        fullArgument: '{ pageId: item?._nid }',
                    });
                    // list.forEach(e => {
                    //   e.extra = [
                    //     `${e.extra || ''}`,
                    //     `.onSizeChange((pre, post) => {`,
                    //     `    if (pre.width === 0 && pre.height === 0) {`,
                    //     `      TaroNativeModule.setTaroNodeAttribute(item, '_style4cpp', \`height:\${post.height}px;width:\${post.width}px;\`)`,
                    //     `    }`,
                    //     `  })`,
                    //   ].filter(e => !!e).join('\n')
                    // })
                };
                compiler.loaderMeta.modifyHarmonyRenderCode = function (code) {
                    const importStr = [
                        `import { ComponentContent, FrameNode, NodeController, UIContext } from '@kit.ArkUI'`,
                        `import { TaroNativeModule } from '@tarojs/runtime'`,
                        `import { TaroXComponent } from '@tarojs/components'`,
                    ];
                    const codeArr = code.split('\n');
                    const idx = codeArr.findIndex(item => !/^(\s*|import\s.+)$/.test(item));
                    importStr.push(...codeArr.splice(0, idx));
                    return this.transArr2Str([
                        ...importStr,
                        '',
                        ...codeArr,
                        '',
                        `@Builder
function createEtsComponent (item: TaroElement) {
  Stack () {
    createChildItem(item, createLazyChildren)
  }
}`,
                        `
export function initEtsBuilder (router = '') {
  TaroNativeModule.registerEtsBuilder((data: TaroElement): ComponentContent<TaroElement> => {
    console.info("registerEtsBuilder app storage has value: " + Current.uiContext?.instanceId_)
    console.info("registerEtsBuilder: " + data._nid)
    return new ComponentContent<TaroElement>(Current.uiContext, wrapBuilder(createEtsComponent), data)
  }, router)
}`, // Note: 直接在 render 中注册会被忽略，需要在 XComponent 中注册
                        '',
                    ]);
                };
            }
            const modifyPageOrComp = (config) => {
                const oddModifyPageImport = config.modifyPageImport;
                config.modifyPageImport = function (importStr, page) {
                    if (shared.isFunction(oddModifyPageImport)) {
                        oddModifyPageImport.call(this, importStr, page);
                    }
                    const { sourceRoot = 'src' } = this.buildConfig;
                    const targetRoot = path.resolve(this.appPath, sourceRoot);
                    const renderPath = path.resolve(targetRoot, 'render');
                    importStr.push(`import { initEtsBuilder } from "${renderPath}"`);
                };
            };
            compiler?.pages?.forEach?.(modifyPageOrComp);
            compiler?.components?.forEach?.(modifyPageOrComp);
        },
    };
}

const babelPresets = [
    [
        require.resolve('@babel/preset-env'), {
            shippedProposals: true,
            targets: 'defaults, not ie 11, not ie_mob 11',
            modules: false,
            useBuiltIns: false,
            // 排除已广泛支持的特性
            exclude: [
                '@babel/plugin-proposal-object-rest-spread',
                '@babel/plugin-proposal-optional-chaining',
                '@babel/plugin-transform-arrow-functions',
                '@babel/plugin-transform-async-to-generator',
                '@babel/plugin-transform-destructuring',
                '@babel/plugin-transform-block-scoped-functions',
                '@babel/plugin-transform-block-scoping',
                '@babel/plugin-transform-classes',
                '@babel/plugin-transform-computed-properties',
                '@babel/plugin-transform-duplicate-keys',
                '@babel/plugin-transform-for-of',
                '@babel/plugin-transform-function-name',
                '@babel/plugin-transform-literals',
                '@babel/plugin-transform-nullish-coalescing-operator',
                '@babel/plugin-transform-object-super',
                '@babel/plugin-transform-parameters',
                '@babel/plugin-transform-shorthand-properties',
                '@babel/plugin-transform-spread',
                '@babel/plugin-transform-sticky-regex',
                '@babel/plugin-transform-template-literals',
                '@babel/plugin-transform-typeof-symbol',
                '@babel/plugin-transform-unicode-regex',
            ],
        }
    ],
    require.resolve('@babel/preset-typescript')
];

/** @deprecated */
function resourcePlugin () {
    return {
        name: 'taro:vite-harmony-resource',
        enforce: 'pre',
        transform(code, id) {
            if (/(\.(et|j|t)sx?|\.vue)$/.test(id.split('?')[0]) && !/node_modules/.test(id)) {
                try {
                    const result = core.transformSync(code, {
                        filename: id,
                        configFile: false,
                        presets: babelPresets,
                        plugins: [
                            (babel) => {
                                const { types: t } = babel;
                                const CurrentLabel = 'Current';
                                let hasCurrentReference = false;
                                return {
                                    visitor: {
                                        Identifier(path) {
                                            if (path.node.name === '$r' &&
                                                !path.scope.hasBinding('$r') &&
                                                path.parent.type !== 'MemberExpression') {
                                                hasCurrentReference = true;
                                                path.replaceWith(t.memberExpression(t.identifier(CurrentLabel), t.identifier('$r')));
                                            }
                                        },
                                        Program: {
                                            exit(path) {
                                                if (hasCurrentReference) {
                                                    let hasCurrentImport = false;
                                                    // 检查是否已有 Current 的导入
                                                    path.node.body.forEach((node) => {
                                                        if (t.isImportDeclaration(node) &&
                                                            node.source.value === '@tarojs/runtime') {
                                                            node.specifiers.forEach((spec) => {
                                                                if (t.isImportSpecifier(spec)) {
                                                                    hasCurrentImport = t.isIdentifier(spec.imported) && spec.imported.name === CurrentLabel;
                                                                }
                                                            });
                                                        }
                                                    });
                                                    // 如果没有，添加导入
                                                    if (!hasCurrentImport) {
                                                        const importDeclaration = t.importDeclaration([
                                                            t.importSpecifier(t.identifier(CurrentLabel), t.identifier(CurrentLabel)),
                                                        ], t.stringLiteral('@tarojs/runtime'));
                                                        path.unshiftContainer('body', importDeclaration);
                                                    }
                                                }
                                            },
                                        },
                                    }
                                };
                            }
                        ]
                    });
                    return {
                        code: result?.code || code,
                        map: result?.map || null,
                    };
                }
                catch (error) {
                    console.error('vite-harmony-resource transform error:', error);
                }
            }
            return null;
        },
    };
}

const STYLE_SUFFIX = '.xss';
const STYLE_SUFFIX_RE = new RegExp(`\\${STYLE_SUFFIX}(\\?\\S+)?$`);
function stylePlugin () {
    const that = this;
    let viteConfigResolved;
    const PageMap = new Map();
    return {
        name: 'taro:vite-harmony-style',
        enforce: 'pre',
        configResolved(config) {
            viteConfigResolved = config;
        },
        async buildStart() {
            const pluginContext = this;
            const { runnerUtils } = that.context;
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = await getViteHarmonyCompilerContext(pluginContext);
            if (compiler) {
                compiler.loaderMeta ||= {};
                compiler.loaderMeta.enableParseJSXStyle = true;
            }
            const modifyPageOrComp = (config) => {
                const oddModifyPageImport = config.modifyPageImport;
                config.modifyPageImport = function (importStr, page) {
                    if (shared.isFunction(oddModifyPageImport)) {
                        oddModifyPageImport.call(this, importStr, page);
                    }
                    const { outputRoot = 'dist', sourceRoot = 'src' } = this.buildConfig;
                    const targetRoot = path.resolve(this.appPath, sourceRoot);
                    if (page instanceof Array) {
                        page.forEach((p, i) => {
                            const styleName = `${p.originName}_style.json`;
                            const styleJsonPath = path.resolve(targetRoot, styleName);
                            importStr.push(`import styleJson${i} from "${styleJsonPath}"`);
                            PageMap.set(path.resolve(outputRoot, styleName), pluginContext.getModuleInfo(p.id));
                        });
                    }
                    else {
                        const styleName = `${page.originName}_style.json`;
                        const styleJsonPath = path.resolve(targetRoot, styleName);
                        importStr.push(`import styleJson from "${styleJsonPath}"`);
                        PageMap.set(path.resolve(outputRoot, styleName), pluginContext.getModuleInfo(page.id));
                    }
                };
            };
            compiler?.pages?.forEach?.(modifyPageOrComp);
            compiler?.components?.forEach?.(modifyPageOrComp);
        },
        async buildEnd() {
            const pluginContext = this;
            const { runnerUtils } = that.context;
            const cacheStyleMap = new Map();
            const { getViteHarmonyCompilerContext } = runnerUtils;
            const compiler = await getViteHarmonyCompilerContext(pluginContext);
            const cssModuleId = new Set();
            if (compiler) {
                PageMap.forEach((moduleInfo, styleJsonPath) => {
                    const list = findStyleInModuleInfo(moduleInfo);
                    const { code } = parseCssToStylesheet.parse(Array.from(list), {
                        platformString: 'Harmony',
                    });
                    if (code) {
                        helper.fs.ensureDirSync(path.dirname(styleJsonPath));
                        helper.fs.writeFileSync(styleJsonPath, code);
                    }
                });
            }
            function findStyleInModuleInfo(moduleInfo, cssList = new Set()) {
                if (!compiler || !moduleInfo)
                    return cssList;
                if (cacheStyleMap.has(moduleInfo.id)) {
                    const list = cacheStyleMap.get(moduleInfo.id);
                    list.forEach((item) => cssList.add(item));
                    return cssList;
                }
                else {
                    cacheStyleMap.set(moduleInfo.id, cssList);
                }
                if (cssModuleId.has(moduleInfo.id)) {
                    return cssList;
                }
                else {
                    cssModuleId.add(moduleInfo.id);
                }
                const styleMap = compiler.loaderMeta.parseJSXStyleMapCache?.get(viteConfigResolved);
                for (const oid of moduleInfo.importedIds) {
                    const id = utils.stripVirtualModulePrefix(oid).replace(STYLE_SUFFIX_RE, '').replace(constants.usedRE, '');
                    if (helper.REG_STYLE.test(id) && styleMap) {
                        if (styleMap.has(id)) {
                            cssList.add(styleMap.get(id));
                        }
                        else if (styleMap.has(id + '?used')) {
                            cssList.add(styleMap.get(id + '?used'));
                        }
                        else {
                            for (const key of styleMap.keys()) {
                                if (key.includes(id) && styleMap.has(key)) {
                                    cssList.add(styleMap.get(key));
                                }
                            }
                        }
                    }
                    else {
                        // Note: 入口文件被供用时，递归查询仍可能造成依赖错误导致样式丢失，当前使用缓存解决
                        findStyleInModuleInfo(pluginContext.getModuleInfo(id), cssList);
                    }
                }
                return cssList;
            }
        },
    };
}

class Harmony extends dist.HarmonyOS_ArkTS {
    get context() {
        return this.ctx;
    }
    constructor(ctx, config, option) {
        // @ts-ignore
        super(ctx, config); // Note: link 时，ctx 类型可能无法对齐，此处忽略类型检查
        this.option = option;
        this.platform = PLATFORM_NAME;
        this.runtimePath = `${PACKAGE_NAME}/dist/runtime/runtime-harmony`;
        this.useETS = true;
        this.useJSON5 = true;
        const that = this;
        this.externalDeps.push([this.runtimePath, new RegExp(`^${this.runtimePath.replace(/([-\\/$])/g, '\\$1')}$`)]);
        this.externalDeps.forEach(e => {
            if (e[0] === '@tarojs/react') {
                e[2] = this.runtimeFrameworkReconciler;
            }
        });
        this.harmonyScope.push(/@(jd|taro)-oh\//, /@kit\./, /^BuildProfile$/);
        this.setupTransaction.addWrapper({
            init() {
                that.modifyPageConfig();
            },
        });
        // Note: 注入 Taro Hooks 相关依赖
        this.apiEntryList = [
            /(@tarojs[\\/]plugin-platform-harmony-cpp|platform-harmony-cpp)[\\/]dist[\\/]runtime[\\/]apischunk[\\/]index\.js/,
        ];
        this.externalDeps.push(['@tarojs/shared', /^@tarojs[\\/]shared$/]);
        this.externalDeps.push(['react-reconciler', /^react-reconciler$/]);
        this.externalDeps.push(['react-reconciler/constants', /^react-reconciler[\\/]constants/]);
        this.externalDeps.push(['scheduler', /^scheduler$/]);
        this.externalDeps.push(['tslib', /^tslib$/]);
    }
    get harmonyPluginPath() {
        let packagePath = '';
        try {
            // Note: 本地或通过包引入
            packagePath = path.dirname(helper.resolveSync('@tarojs/plugin-platform-harmony-ets'));
        }
        catch (e) { } // eslint-disable-line no-empty
        if (!packagePath) {
            // Note: Link 引入
            packagePath = path.dirname(helper.resolveSync('@tarojs/plugin-platform-harmony-ets', { basedir: process.cwd() }));
        }
        return packagePath;
    }
    get harmonyCppPluginPath() {
        let packagePath = '';
        try {
            // Note: 本地或通过包引入
            packagePath = path.dirname(helper.resolveSync(PACKAGE_NAME));
        }
        catch (e) { } // eslint-disable-line no-empty
        if (!packagePath) {
            try {
                // Note: Link 引入
                packagePath = path.dirname(helper.resolveSync(PACKAGE_NAME, { basedir: process.cwd() }));
            }
            catch (e) { } // eslint-disable-line no-empty
        }
        if (!packagePath) {
            // Note: 本地 build-library 时，可能会找不到自己，此时使用 process.cwd() 作为 fallback
            packagePath = process.cwd();
        }
        return packagePath;
    }
    get apiLibrary() {
        return path.resolve(this.harmonyCppPluginPath, 'dist', './runtime/apischunk');
    }
    get componentLibrary() {
        return path.join(this.harmonyCppPluginPath, 'dist', './runtime/components');
    }
    get runtimeLibrary() {
        return path.join(this.harmonyCppPluginPath, 'dist', './runtime/runtime-cpp');
    }
    get runtimeFrameworkLibrary() {
        return path.join(this.harmonyCppPluginPath, 'dist', `./runtime/framework`);
    }
    get runtimeFrameworkReconciler() {
        return path.join(this.harmonyCppPluginPath, 'dist', `./runtime/framework-reconciler`);
    }
    modifyPageConfig() {
        const that = this;
        that.ctx.modifyViteConfig?.(opt => {
            opt.viteConfig.plugins.push(appPlugin.call(this, opt), pagePlugin.call(this, opt), renderPlugin.call(this, opt), resourcePlugin.call(this, opt), stylePlugin.call(this, opt), injectEnv.call(this, opt));
        });
    }
    // Note: 更新 oh-package 中项目依赖声明
    updateModulePackage(outputRoot, ohPackage = {}, ohpm) {
        const packageJsonFile = path.join(outputRoot, `${this.useJSON5 !== false ? 'oh-package.json5' : 'package.json'}`);
        const isExists = helper.fs.pathExistsSync(packageJsonFile);
        if (!isExists)
            return;
        const pkg = helper.recursiveMerge(harmony.readJsonSync(packageJsonFile), ohPackage);
        pkg.types = './src/main/ets/npm/@tarojs/taro/index.d.ts';
        helper.fs.writeJsonSync(packageJsonFile, pkg, { spaces: 2 });
        let ohpmPath = ohpm;
        let localOhpmPath = '';
        try {
            localOhpmPath = node_child_process.execSync(`${process?.platform === 'win32' ? 'where' : 'which'} ohpm`).toString().replace(/\n/, '');
        }
        catch (_) {
            localOhpmPath = '';
        }
        ohpmPath = ohpm || localOhpmPath || '~/Library/Huawei/ohpm/bin/ohpm';
        try {
            console.log(`开始 ${helper.chalk.yellow('ohpm install')} 脚本执行...\n`); // eslint-disable-line no-console
            node_child_process.execSync(`${ohpmPath} install`, { cwd: outputRoot, stdio: 'inherit' });
            console.log(`执行 ${helper.chalk.yellow('ohpm install')} 脚本成功。\n`); // eslint-disable-line no-console
        }
        catch (e) {
            console.error(`自动安装依赖失败，请手动执行 ${helper.chalk.yellow('ohpm install')} 或在 DevEco Studio 中打开 oh-package.json5 并点击 ${helper.chalk.yellow('Sync Now')} 按钮`);
        }
        if (pkg.main) {
            const mainPath = path.join(outputRoot, pkg.main);
            helper.fs.writeFileSync(mainPath, `export * from './src/main/ets/${NPM_DIR}/@tarojs/taro'`);
        }
    }
}

/* eslint-disable no-console */
const argProjectPath = getProcessArg('lib');
const argHapName = getProcessArg('hap');
let harName = `${PKG_NAME}-${PKG_VERSION}.har`;
if (!helper.fs.existsSync(path.join(__dirname, '..', STATIC_FOLDER_NAME, harName))) {
    harName = require('fast-glob').sync('**/*.har', { cwd: path.join(__dirname, '..', STATIC_FOLDER_NAME) })[0] || '';
}
var index = (ctx, options = {}) => {
    options.useChoreLibrary = options.useChoreLibrary ?? 'local';
    // 合并 harmony 编译配置到 opts
    ctx.modifyRunnerOpts(({ opts }) => {
        if (opts.platform !== PLATFORM_NAME)
            return;
        opts.ohPackage ||= {};
        opts.ohPackage.dependencies ||= {};
        if (options.useChoreLibrary) {
            opts.chorePackagePrefix ||= `${PKG_NAME}/src/main/ets/${helper.NPM_DIR}`;
            if (options.useChoreLibrary === 'local') {
                if (!harName) {
                    console.warn(helper.chalk.yellow('未找到 .har 文件。'));
                }
                opts.ohPackage.dependencies[PKG_NAME] ||= `file:../static/${harName}`;
            }
            else if (options.useChoreLibrary === 'remote') {
                opts.ohPackage.dependencies[PKG_NAME] ||= `^${PKG_VERSION}`;
            }
            else {
                opts.ohPackage.dependencies[PKG_NAME] ||= options.useChoreLibrary;
            }
            PROJECT_DEPENDENCIES_NAME.forEach(key => {
                opts.ohPackage.dependencies[key] ||= PKG_DEPENDENCIES[key];
            });
        }
        else {
            Object.keys(PKG_DEPENDENCIES).forEach(key => {
                opts.ohPackage.dependencies[key] ||= PKG_DEPENDENCIES[key];
            });
            opts.ohPackage.dependencies[CPP_LIBRARY_NAME] = CPP_LIBRARY_PATH;
        }
        const harmonyConfig = ctx.ctx.initialConfig.harmony;
        assertHarmonyConfig(ctx, harmonyConfig);
        const terserOptions = harmonyConfig?.terser || ctx.initialConfig.terser || { config: constants$1.DEFAULT_TERSER_OPTIONS };
        terserOptions.config ||= {};
        terserOptions.config.output ||= {};
        terserOptions.config.output.comments ||= /^!/; // Note: 避免删除第一行注释影响 rawfile 代码缓存
        harmonyConfig.name ||= 'default';
        harmonyConfig.hapName ||= argHapName || 'entry';
        const { projectPath, hapName } = harmonyConfig;
        opts.outputRoot = path.join(argProjectPath || projectPath, hapName, 'src/main', 'ets');
        opts.harmony = harmonyConfig;
        ctx.paths.outputPath = opts.outputRoot;
    });
    ctx.registerPlatform({
        name: PLATFORM_NAME,
        useConfigName: options.useConfigName || 'harmony',
        async fn({ config }) {
            const program = new Harmony(ctx, config, options);
            await program.start();
            const { projectPath, hapName = 'entry', outputRoot } = config;
            if (!options.useChoreLibrary) {
                if (hapName !== 'entry') { // Note: 如果是 entry 不需要重写 BuildProfile 路径
                    fixBuildProfile(outputRoot, path.join(outputRoot, '../../..'));
                }
                const buildProfilePath = path.join(projectPath, hapName, `build-profile.${program.useJSON5 !== false ? 'json5' : 'json'}`);
                updateBuildProfile(buildProfilePath, hapName);
                const C_API_TXT = helper.chalk.yellow('C-API');
                try {
                    const cppOutPath = path.join(projectPath, hapName, 'src/main', 'cpp');
                    if (!helper.fs.existsSync(cppOutPath)) {
                        console.log(`开始拉取 ${C_API_TXT} 模块...`);
                        node_child_process.execSync(`git clone https://github.com/NervJS/taro-harmony-capi-library.git  ${cppOutPath}`, {
                            cwd: path.resolve(__dirname, '..', '..', '..'),
                            stdio: 'inherit',
                            env: process.env,
                        });
                    }
                }
                catch (error) {
                    console.log(`${C_API_TXT} 获取失败...`); // eslint-disable-line no-console
                }
            }
            else if (options.useChoreLibrary === 'local' && harName) {
                const harPath = path.join(argProjectPath || projectPath, STATIC_FOLDER_NAME, harName);
                const harDir = path.dirname(harPath);
                helper.fs.ensureDirSync(harDir);
                helper.fs.emptyDirSync(harDir);
                helper.fs.copyFileSync(path.join(program.harmonyCppPluginPath, STATIC_FOLDER_NAME, harName), harPath);
            }
        }
    });
};
function assertHarmonyConfig(ctx, config) {
    const NOTE_INVALID = helper.chalk.red('[✗] ');
    const errorChalk = helper.chalk.hex('#f00');
    const lineChalk = helper.chalk.hex('#fff');
    function throwError(err) {
        console.log(errorChalk(`Taro 配置有误，请检查！ (${ctx.paths.configPath})`));
        console.log(`  ${NOTE_INVALID}${lineChalk(err)}`);
        process.exit(0);
    }
    if (typeof config !== 'object' || !config) {
        throwError('请设置 harmony 编译配置');
    }
    if (!config.projectPath) {
        throwError('请设置 harmony.projectPath');
    }
}

exports.HarmonyCPP = Harmony;
exports.default = index;
