"use strict";
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());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const body_parser_1 = __importDefault(require("body-parser"));
const fs = __importStar(require("fs-extra"));
const inquirer_1 = __importDefault(require("inquirer"));
const node_watch_1 = __importDefault(require("node-watch"));
const open_1 = __importDefault(require("open"));
const path = __importStar(require("path"));
const process = __importStar(require("process"));
const webpack_1 = __importDefault(require("webpack"));
const webpack_dev_server_1 = __importDefault(require("webpack-dev-server"));
const autoRequire = __importStar(require("../tools/scripts/autoRequire"));
const generateMeta = __importStar(require("../tools/scripts/generateMeta"));
const generateStyleSchema = __importStar(require("../tools/scripts/generateStyleSchema"));
const webpackConfig = __importStar(require("../tools/webpack"));
const util_1 = require("../util");
const preview_1 = require("./preview");
function clearTemp(paths) {
    return __awaiter(this, void 0, void 0, function* () {
        util_1.logWithSpinner('💭', '清除缓存');
        yield Promise.all([
            fs.emptyDir(paths.tempPath),
            fs.emptyDir(paths.outputPath),
        ]);
        util_1.stopSpinner();
    });
}
function webpackCallback(resolve, reject) {
    return (err, stats) => {
        if (err) {
            util_1.error('fatal webpack errors:', (err.stack.toString() || err.toString()).trim());
            if (err.details) {
                util_1.error('fatal webpack errors:', err.details.trim());
            }
            reject();
        }
        const info = stats.toJson();
        if (stats.hasErrors()) {
            info.errors.forEach((e) => {
                if (e.trim()) {
                    util_1.error('\n\nWebpack compilation errors:', e.trim());
                }
            });
            return reject();
        }
        return resolve();
    };
}
function beforeDist(paths, container) {
    return __awaiter(this, void 0, void 0, function* () {
        yield clearTemp(paths);
        util_1.logWithSpinner('⛽️', '执行前置脚本');
        autoRequire.writeTempFile(paths, container);
        util_1.stopSpinner();
        util_1.logWithSpinner('📃', '生成 MetaTemp 文件');
        generateMeta.writeTempFile(paths);
        util_1.logWithSpinner('📃', '生成 StyleSchemaTemp 文件');
        generateStyleSchema.writeTempFile(paths);
        util_1.stopSpinner();
        runWatchServer(paths);
    });
}
function afterUpdate(paths, container) {
    return __awaiter(this, void 0, void 0, function* () {
        util_1.logWithSpinner('🔥', '重新执行前置脚本');
        autoRequire.writeTempFile(paths, container);
        util_1.stopSpinner();
    });
}
function afterDist(paths) {
    util_1.logWithSpinner('⛽️', '执行后置脚本');
    generateMeta.generateMeta(paths);
    generateStyleSchema.generateStyleSchema(paths);
    util_1.stopSpinner();
}
function runDevServer(paths, port, container) {
    return __awaiter(this, void 0, void 0, function* () {
        return new Promise((resolve, reject) => {
            util_1.logWithSpinner('💫', '生成 Webpack 配置');
            const config = webpackConfig.getLibDevConfig(paths);
            util_1.stopSpinner();
            util_1.log('启动 Dev Server...');
            const compiler = webpack_1.default(config);
            new webpack_dev_server_1.default(compiler, {
                hot: true,
                inline: false,
                contentBase: [paths.editorPath, path.resolve(process.cwd(), 'dist')],
                compress: false,
                headers: {
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Headers': '*',
                },
                after: function (app, server) {
                    openEditor(paths, 4567);
                },
                setup: function (app, server) {
                    app.post('/cgi/preview', body_parser_1.default.json(), function (req, res) {
                        preview_1.preview(req, res, paths, container);
                    });
                },
            }).listen(port);
        });
    });
}
function runBuild(paths) {
    util_1.logWithSpinner('💫', '生成 Webpack 配置');
    const config = webpackConfig.getLibProdConfig(paths);
    util_1.stopSpinner();
    util_1.log('启动 Webpack 构建...');
    return new Promise((resolve, reject) => {
        webpack_1.default(config).run(webpackCallback(resolve, reject));
    });
}
function runMetaBuild(paths) {
    util_1.logWithSpinner('💫', '生成 Meta Webpack 配置');
    const config = webpackConfig.getLibMetaConfig(paths);
    util_1.stopSpinner();
    util_1.log('⚡️ 启动 Meta 构建...');
    return new Promise((resolve, reject) => {
        webpack_1.default(config).run(webpackCallback(resolve, reject));
    });
}
function runSchemaBuild(paths) {
    util_1.logWithSpinner('💫', '生成 Style Schema Webpack 配置');
    const config = webpackConfig.getLibSchemaConfig(paths);
    util_1.stopSpinner();
    util_1.log('⚡️ 启动 Style Schema 构建...');
    return new Promise((resolve, reject) => {
        webpack_1.default(config).run(webpackCallback(resolve, reject));
    });
}
function openEditor(paths, port) {
    // const process = require('process');
    // process.env.PATH = [
    //   process.env.PATH,
    //   path.resolve(process.cwd(), './node_modules/.bin'),
    // ].join(os.platform() === 'win32' ? ';' : ':');
    // const editorPath = path.resolve(__dirname, '../../static/editor');
    const { version } = require(path.resolve(__dirname, '../../package.json'));
    const filename = `cli-debug-v${version}.html`;
    // const p = exec(`serve ${editorPath} -l 4566`, {
    //   env: process.env,
    // });
    // p.stdout.on('data', log).on('error', error);
    // p.stderr.on('data', log).on('error', error);
    const url = `http://127.0.0.1:${port}/${filename}?debugPort=4567&libName=${paths.libName}`;
    setTimeout(() => open_1.default(url), 5000);
}
function runWatchServer(paths) {
    util_1.logWithSpinner('🤖', '启动 File Watcher');
    ['components', 'plugins', 'actions'].forEach((name) => {
        node_watch_1.default(path.resolve(paths.srcPath, `./${name}`), { recursive: false }, () => {
            util_1.log(`🔥  ${name} 目录更新`);
            return afterUpdate(util_1.getPaths(paths.rootPath));
        });
    });
    util_1.stopSpinner();
}
function devServer(name, options) {
    return __awaiter(this, void 0, void 0, function* () {
        if (options.proxy) {
            process.env.http_proxy = options.proxy;
        }
        const paths = util_1.getPaths(process.cwd());
        const containers = Object.keys(paths.containersMap);
        let container;
        if (containers.length) {
            if (containers.length === 1) {
                container = containers[0];
            }
            else {
                const { container: c } = yield inquirer_1.default.prompt([
                    {
                        type: 'list',
                        name: 'container',
                        message: '选择 Container',
                        default: containers[0],
                        choices: containers,
                    },
                ]);
                container = c;
            }
        }
        try {
            yield beforeDist(paths, container);
            yield runDevServer(paths, 4567, container);
        }
        catch (err) {
            util_1.stopSpinner(false);
            util_1.error(err);
            process.exit(1);
        }
    });
}
exports.devServer = devServer;
function build(name, options) {
    return __awaiter(this, void 0, void 0, function* () {
        if (options.proxy) {
            process.env.http_proxy = options.proxy;
        }
        try {
            const paths = util_1.getPaths(process.cwd());
            yield beforeDist(paths);
            yield runBuild(paths);
            yield runMetaBuild(paths);
            yield runSchemaBuild(paths);
            afterDist(paths);
            util_1.log('构建成功', 'ok');
        }
        catch (err) {
            util_1.stopSpinner(false);
            util_1.error(err);
            process.exit(1);
        }
    });
}
exports.build = build;
//# sourceMappingURL=buildLibrary.js.map