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());
    });
};
const fs = require('fs');
const path = require('path');
const Handlebars = require('handlebars');
const chalk = require('chalk');
const { parse } = require('@babel/parser');
const traverse = require('@babel/traverse');
const upperFirst = require('lodash/upperFirst');
const { compileProject, compileModule } = require('./transformDSL');
const { compileSwaggerData, compileEntityData } = require('./utils');
const transformDSL = (transData, client) => __awaiter(this, void 0, void 0, function* () {
    const { projectPath, jwtToken, envCode, appCode, token, tenant, graphqlUrl, microInfo, ssoAuthUrl, ssoAppKey, previewHost } = transData;
    let { childModuleFlag } = transData;
    const { microId, microName = 'frontend', microVersion = '0.0.1', microDescription = 'Fishx空模板', microPageList = '[]', microType } = microInfo || {};
    // 一键发布分为达芬奇无代码和门户集成两种方式, 门户方式同childModule
    if (microType === 'portal') {
        childModuleFlag = 'childModule';
    }
    const projectConfigContent = fs.readFileSync(path.join(projectPath, '.projectType')).toString();
    let themeFileName = 'fdx-dc.min.css';
    if (fs.existsSync(path.join(projectPath, 'UI/Themes/themes.json'))) {
        const themeContent = fs.readFileSync(path.join(projectPath, 'UI/Themes/themes.json')).toString();
        const theme = JSON.parse(themeContent)[0];
        themeFileName = theme.css || 'fdx-dc.min.css';
    }
    let projectName;
    let envName;
    if (envCode && appCode) {
        projectName = appCode;
        envName = envCode;
    }
    else {
        projectName = projectConfigContent.match(/projectName\s=\s(\S*?);/)[1];
        envName = projectConfigContent.match(/envName\s=\s(\S*?);/) ? projectConfigContent.match(/envName\s=\s(\S*?);/)[1] : '';
    }
    const defaultDateFormat = projectConfigContent.match(/defaultDateFormat\s=\s(\S*?);/) ? projectConfigContent.match(/defaultDateFormat\s=\s(\S*?);/)[1] : '';
    const defaultYearFormat = projectConfigContent.match(/defaultYearFormat\s=\s(\S*?);/) ? projectConfigContent.match(/defaultYearFormat\s=\s(\S*?);/)[1] : '';
    const defaultMonthFormat = projectConfigContent.match(/defaultMonthFormat\s=\s(\S*?);/) ? projectConfigContent.match(/defaultMonthFormat\s=\s(\S*?);/)[1] : '';
    const defaultWeekFormat = projectConfigContent.match(/defaultWeekFormat\s=\s(\S*?);/) ? projectConfigContent.match(/defaultWeekFormat\s=\s(\S*?);/)[1] : '';
    const defaultTimeFormat = projectConfigContent.match(/defaultTimeFormat\s=\s(\S*?);/) ? projectConfigContent.match(/defaultTimeFormat\s=\s(\S*?);/)[1] : '';
    const microBasename = projectConfigContent.match(/basename\s=\s(\S*?);/) ? projectConfigContent.match(/basename\s=\s(\S*?);/)[1] : '';
    const antPrefixCls = projectConfigContent.match(/antPrefixCls\s=\s(\S*?);/) ? projectConfigContent.match(/basename\s=\s(\S*?);/)[1] : '';
    console.log(chalk.blue(`projectName: ${projectName}`));
    console.log(chalk.blue(`envName: ${envName}`));
    console.log(chalk.blue(`basename: ${microBasename}`));
    console.log(chalk.blue(`antPrefixCls: ${antPrefixCls}`));
    console.log(chalk.blue(`defaultDateFormat: ${defaultDateFormat}`));
    console.log(chalk.blue(`defaultYearFormat: ${defaultYearFormat}`));
    console.log(chalk.blue(`defaultMonthFormat: ${defaultMonthFormat}`));
    console.log(chalk.blue(`defaultWeekFormat: ${defaultWeekFormat}`));
    console.log(chalk.blue(`defaultTimeFormat: ${defaultTimeFormat}`));
    // envName 可能不一定存在
    const gatewayName = envName && process.env.TRIGGER_SOURCE !== 'DOS' ? `${envName}_${projectName}`.toLowerCase() : projectName.toLowerCase();
    console.log(chalk.blue(`gatewayName: ${gatewayName}`));
    const fishxConfigTplPath = path.join(projectPath, 'generatedCode/frontend/.fishx.config.hbs');
    const dockerfileTplPath = path.join(projectPath, 'generatedCode/frontend/.Dockerfile.hbs');
    const fishxConfigJsPath = path.join(projectPath, 'generatedCode/frontend/fishx.config.ts');
    const graphqlClientJsPath = path.join(projectPath, 'generatedCode/frontend/src/utils/util.ts');
    const graphqlClientJsTplPath = path.join(projectPath, 'generatedCode/frontend/.util.hbs');
    const indexPath = path.join(projectPath, 'generatedCode/frontend/src/global.less');
    const nginxConfigTplPath = path.join(projectPath, 'generatedCode/frontend/.nginx.conf.hbs');
    const nginxConfigPath = path.join(projectPath, 'generatedCode/frontend/nginx.conf');
    const packageJsonTplPath = path.join(projectPath, 'generatedCode/frontend/.package.hbs');
    const packageJsonPath = path.join(projectPath, 'generatedCode/frontend/package.json');
    const configTplPath = path.join(projectPath, 'generatedCode/frontend/.config.hbs');
    const configPath = path.join(projectPath, 'generatedCode/frontend/src/config/config.js');
    const dockerfilePath = path.join(projectPath, 'generatedCode/frontend/Dockerfile');
    const fishxConfigContent = fs.readFileSync(fishxConfigTplPath, 'utf-8');
    const dockerfileContent = fs.readFileSync(dockerfileTplPath, 'utf-8');
    const nginxContent = fs.readFileSync(nginxConfigTplPath, 'utf-8');
    const graphqlClientJsContent = fs.readFileSync(graphqlClientJsTplPath, 'utf-8');
    const indexContent = fs.readFileSync(indexPath, 'utf-8');
    const packageJsonContent = fs.readFileSync(packageJsonTplPath, 'utf-8');
    const configContent = fs.readFileSync(configTplPath, 'utf-8');
    const fishxConfigTemplate = Handlebars.compile(fishxConfigContent);
    const dockerfileTemplate = Handlebars.compile(dockerfileContent);
    const nginxTemplate = Handlebars.compile(nginxContent);
    const graphqlClientJsTemplate = Handlebars.compile(graphqlClientJsContent);
    const packageJsonTemplate = Handlebars.compile(packageJsonContent);
    const configTemplate = Handlebars.compile(configContent);
    console.log(chalk.blue('start transform dsl...'));
    if (indexContent.indexOf('CSSFILE') !== -1) {
        const newIndexContent = indexContent.replace('CSSFILE', themeFileName);
        fs.writeFileSync(indexPath, newIndexContent, { encoding: 'utf8' });
    }
    // 渲染fishx.config.ts 的参数
    const fishxConfigData = {
        GATEWAYNAME: gatewayName,
        graphqlUrl,
        PREVIEW_HOST: previewHost,
        ZCM_APP: ssoAppKey === 'Cxkgf7BovAZZFN86e5rl',
    };
    // 是否是无代码扩展包（微前端）
    if (microInfo && microInfo.microId && microType !== 'portal') {
        fishxConfigData.IS_MICRO = true;
    }
    // 渲染fishx.config.ts 的参数
    const packageJsonData = {
        MICRO_ID: microId,
        MICRO_NAME: microName,
        MICRO_VERSION: microVersion,
        MICRO_DESC: microDescription,
    };
    // 渲染 src/config/config.js 的参数
    const configData = {
        MICRO_PAGE_LIST: microPageList,
        IS_MICRO: !!((microInfo && microInfo.microId && microType !== 'portal')),
    };
    // 通过参数确认是否是微前端构建流程
    if (childModuleFlag === 'childModule') {
        console.log(chalk.blue('正在使用微前端模板'));
        fishxConfigData.CHILD_MODULE_FLAG = true;
    }
    if (childModuleFlag === 'widget') {
        fishxConfigData.WIDGET_FLAG = true;
        let allWidgets = [];
        if (fs.existsSync(path.join(projectPath, '/UI/UI Flows/Widget'))) {
            allWidgets = fs.readdirSync(path.join(projectPath, '/UI/UI Flows/Widget'));
            allWidgets = allWidgets.filter(v => v !== '.gitkeep').map(v => upperFirst(v));
        }
        fishxConfigData.ALL_WIDGETS = allWidgets;
    }
    if (ssoAppKey) {
        fishxConfigData.SSO_LOGGED = `'/portal/logged': {
      target: '${ssoAppKey === 'Cxkgf7BovAZZFN86e5rl' ? 'https://dev.iwhalecloud.com' : 'https://zmp.iwhalecloud.com'}',
      changeOrigin: true,
      onProxyRes,
    },`;
    }
    // 生成src/utils/util.ts文件
    const graphqlClientJs = graphqlClientJsTemplate({
        GATEWAYNAME: gatewayName,
        JWTTOKEN: jwtToken,
        SSO_AUTH_URL: ssoAuthUrl,
        SSO_APP_KEY: ssoAppKey,
        token,
        tenant,
        DEFAULT_DATE_FORMAT: defaultDateFormat,
        DEFAULT_YEAR_FORMAT: defaultYearFormat,
        DEFAULT_MONTH_FORMAT: defaultMonthFormat,
        DEFAULT_WEEK_FORMAT: defaultWeekFormat,
        DEFAULT_TIME_FORMAT: defaultTimeFormat,
        MICRO_BASENAME: microBasename,
        ANT_PREFIX_CLS: antPrefixCls,
    });
    // 生成 fishx.config.ts 配置文件
    const fishxConfig = fishxConfigTemplate(fishxConfigData);
    fs.writeFileSync(fishxConfigJsPath, fishxConfig, { encoding: 'utf8' });
    // 生成 package.json 配置文件
    const packageJsonConfig = packageJsonTemplate(packageJsonData);
    fs.writeFileSync(packageJsonPath, packageJsonConfig, { encoding: 'utf8' });
    // 生成config.js 配置文件 （用于无代码扩展包路由配置）
    const configFileConfig = configTemplate(configData);
    fs.writeFileSync(configPath, configFileConfig, { encoding: 'utf8' });
    // 生成 Dockerfile 配置文件
    const dockerfileConfig = dockerfileTemplate({
        GATEWAYNAME: gatewayName,
    });
    // 生成 nginx.conf 配置文件
    const nginxConfig = nginxTemplate({
        GATEWAYNAME: gatewayName,
    });
    fs.writeFileSync(dockerfilePath, dockerfileConfig, { encoding: 'utf8' });
    fs.writeFileSync(nginxConfigPath, nginxConfig, { encoding: 'utf8' });
    fs.writeFileSync(graphqlClientJsPath, graphqlClientJs, { encoding: 'utf8' });
    if (!fs.existsSync(path.join(projectPath, 'generatedCode/frontend/src/types'))) {
        fs.mkdirSync(path.join(projectPath, 'generatedCode/frontend/src/types'));
    }
    const types = fs.readdirSync(path.join(projectPath, 'Data/Interface'));
    let commonTypes = '';
    let itemContent;
    types.forEach(item => {
        const statObj = fs.statSync(path.join(projectPath, 'Data/Interface', item));
        if (statObj.isDirectory()) {
            const pages = fs.readdirSync(path.join(projectPath, 'Data/Interface', item));
            pages.forEach(page => {
                const stat = fs.statSync(path.join(projectPath, 'Data/Interface', item, page));
                if (stat.isDirectory()) {
                    const pageItems = fs.readdirSync(path.join(projectPath, 'Data/Interface', item, page));
                    pageItems.forEach(v => {
                        if (v === 'commonQuery.ts') {
                            itemContent = "import { List } from '@/utils/ProjectType';\n";
                            itemContent += fs.readFileSync(path.join(projectPath, 'Data/Interface', item, page, v)).toString();
                            itemContent = itemContent.replace(/let\s/g, 'export let ');
                            itemContent = itemContent.replace(/const\s/g, 'export const ');
                            itemContent = itemContent.replace(/class\s/g, 'export class ');
                            itemContent = itemContent.replace(/interface\s/g, 'export interface ');
                            fs.writeFileSync(path.join(projectPath, `generatedCode/frontend/src/types/${page}.ts`), itemContent);
                        }
                    });
                }
            });
        }
        else {
            if (item === 'base.ts') {
                commonTypes = fs.readFileSync(path.join(projectPath, 'Data/Interface', item)).toString();
            }
            // 读取用户自己创建的 server action 的类型文件
            if (item === 'userServeAction.d.ts') {
                userServerTypes = fs.readFileSync(path.join(projectPath, 'Data/Interface', item)).toString();
                let serverList = {};
                const ast = parse(userServerTypes, {
                    plugins: ['typescript'],
                });
                traverse.default(ast, {
                    TSInterfaceDeclaration(path) {
                        if (path.node.id.name === 'UserServeActionProps') {
                            path.node.body.body.forEach((n) => {
                                const paramsArr = [];
                                if (Array.isArray(n.typeAnnotation.typeAnnotation.parameters)) {
                                    n.typeAnnotation.typeAnnotation.parameters.forEach(p => {
                                        paramsArr.push(p.name);
                                    });
                                }
                                serverList[n.key.name] = paramsArr;
                            });
                        }
                    },
                });
                serverList = JSON.stringify(serverList);
                fs.writeFileSync(path.join(projectPath, 'generatedCode/frontend/src/utils/userServerTypes.ts'), `export const serverActionList = ${serverList}`);
            }
        }
    });
    commonTypes = commonTypes.replace(/let\s/g, 'export let ');
    commonTypes = commonTypes.replace(/const\s/g, 'export const ');
    commonTypes = commonTypes.replace(/class\s/g, 'export class ');
    commonTypes = commonTypes.replace(/interface\s/g, 'export interface ');
    fs.writeFileSync(path.join(projectPath, 'generatedCode/frontend/src/utils/ProjectType.ts'), commonTypes);
    // 生成 swagger 相关内容
    compileSwaggerData(projectPath);
    // 生成 entity 相关内容
    compileEntityData(projectPath);
    const res = yield compileProject(projectPath, projectName, client);
    return res;
});
module.exports = {
    transformDSL,
    compileModule,
    compileSwaggerData,
    compileEntityData,
};
