"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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const Path = require("path");
const FS = require("fs");
const ChildProcess = require("child_process");
const Walk = require("walk");
const cube_utils_1 = require("./cube-utils");
const cube_project_1 = require("./cube-project");
const cube_pack_template_loader_1 = require("./cube-pack-template-loader");
class ACPack {
    constructor() {
        this._wxtoolPath = Path.join(process.env.HOME ? process.env.HOME : '', '.antcube/wxtool');
        this._tempLoader = new cube_pack_template_loader_1.ACPackTemplateLoader();
    }
    isReady() {
        return true;
    }
    buildProject(path, output) {
        return __awaiter(this, void 0, void 0, function* () {
            const pkg = cube_utils_1.ACUtils.pickProjectPackage(path);
            switch (pkg.type) {
                case cube_project_1.ACProjectType.ACProjectApplication:
                    if (pkg.subtype === 'app') {
                        return yield this.buildApplication(path, output);
                    }
                    return Promise.reject(new Error(`无效的待编译项目子类型 [${pkg.subtype}] [${path}]`));
                case cube_project_1.ACProjectType.ACProjectTemplates:
                    return yield this.buildTemplates(path, output);
                default:
                    return Promise.reject(new Error(`未发现可编译项目 [${path}]`));
            }
        });
    }
    buildFile(path, output) {
        return __awaiter(this, void 0, void 0, function* () {
            return this.buildApplication(path, output, false);
        });
    }
    buildApplication(path, output, isProject = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const result = yield cube_utils_1.ACUtils.spawn(`node`, [Path.join(this._wxtoolPath, 'dist/index.js'), (isProject ? '-p' : '-f'), path, '-o', output]);
            if (result.status === 0) {
                return Promise.resolve({ success: true, message: result.stdout.toString() });
            }
            else {
                return Promise.reject({ success: false, message: result.stderr.toString() });
            }
        });
    }
    buildTemplates(path, output, isProject = true) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, rejects) => {
                const errMsgs = new Array();
                //  准备
                cube_utils_1.ACUtils.rmdirs(output);
                cube_utils_1.ACUtils.mkdirs(output);
                //  解析转译
                const builders = new Array();
                const pickTplDistPath = (root) => {
                    const manifest = JSON.parse(FS.readFileSync(Path.join(root, 'manifest.json')).toString());
                    if (manifest.name) {
                        const distpath = Path.join(output, `${manifest.name}`);
                        if (!FS.existsSync(distpath)) {
                            FS.mkdirSync(distpath);
                        }
                        return distpath;
                    }
                    else {
                        return '';
                    }
                };
                Walk.walkSync(path, {
                    listeners: {
                        file: (root, names, next) => {
                            if (names.type === 'file' && names.name === 'main.vue') {
                                builders.push(this._tempLoader.build(Path.join(root, names.name)).then(value => {
                                    const distpath = pickTplDistPath(root);
                                    value.meta = FS.readFileSync(Path.join(root, 'manifest.json')).toString();
                                    const jsonpath = Path.join(distpath, `main.json`);
                                    FS.writeFileSync(jsonpath, JSON.stringify(value, undefined, 2), { encoding: 'utf8' });
                                    const binpath = Path.join(distpath, 'main.bin');
                                    const cmd = Path.join(cube_utils_1.ACUtils.respath, 'capnp/falcon_convert');
                                    const schema = Path.join(cube_utils_1.ACUtils.respath, 'capnp/cube-v1.capnp');
                                    const ccapnp = ChildProcess.spawnSync(cmd, [schema, jsonpath, binpath]);
                                    if (ccapnp.status !== 0) {
                                        errMsgs.push(new Error(`${ccapnp.stderr.toString()}`));
                                    }
                                }).finally(() => {
                                    next();
                                }));
                            }
                            else if (names.type === 'file' && Path.extname(names.name) === '.json' && names.name.indexOf('mock') === 0) {
                                const distpath = pickTplDistPath(root);
                                const mockpath = Path.join(distpath, 'main.mock');
                                let mock = new Array();
                                if (FS.existsSync(mockpath)) {
                                    mock = JSON.parse(FS.readFileSync(mockpath).toString());
                                }
                                mock.push({
                                    data: FS.readFileSync(Path.join(root, names.name)).toString()
                                });
                                FS.writeFileSync(mockpath, JSON.stringify(mock, undefined, 2), { encoding: 'utf8' });
                            }
                            else {
                                next();
                            }
                        },
                        errors: (root, names, next) => {
                            errMsgs.push(new Error('遍历编译路径失败'));
                            next();
                        }
                    }
                });
                Promise.all(builders).then(results => {
                    resolve({
                        success: errMsgs.length === 0 ? true : false,
                        message: errMsgs.length !== 0 ? `${errMsgs.join('\n')}` : ''
                    });
                }).catch(reason => {
                    rejects({
                        success: false,
                        message: errMsgs.length !== 0 ? `${errMsgs.join('\n')}` : ''
                    });
                });
            });
        });
    }
}
exports.default = ACPack;
//# sourceMappingURL=cube-pack.js.map