"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 __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 Utils = __importStar(require("../../util/src"));
const Path = __importStar(require("path"));
const FS = __importStar(require("fs"));
const Store = __importStar(require("./store"));
const urlencode_1 = __importStar(require("urlencode")), Urlencode = urlencode_1;
const Http = __importStar(require("http"));
const UrlQuery = __importStar(require("query-string"));
class FTPBridge {
    constructor() {
        this.server = Http.createServer();
        this.port = 9090;
    }
    run() {
        return __awaiter(this, void 0, void 0, function* () {
            yield Utils.Net.cleanPort(this.port);
            this.server.on('request', (request, response) => {
                Utils.Console.info(`receive request : ${request.url}`);
                const queryinfo = UrlQuery.parseUrl(`${request.url}`);
                if (queryinfo.url === '/api') {
                    switch (queryinfo.query.action) {
                        case 'file':
                            const path = `${queryinfo.query.path}`;
                            if (FS.existsSync(path)) {
                                response.statusCode = 200;
                                response.end(FS.readFileSync(path));
                            }
                            else {
                                response.statusCode = 201;
                                response.end();
                            }
                            break;
                        default:
                            response.statusCode = 404;
                            response.end();
                            break;
                    }
                }
                else {
                    response.statusCode = 404;
                    response.end();
                }
                Utils.Console.info(`post response : ${response.statusCode}`);
            });
            return new Promise((resolve, reject) => {
                this.server.listen(this.port, () => {
                    Utils.Console.info(`${Utils.ACUtils.localIP()}:${this.port}`);
                    resolve();
                });
            });
        });
    }
    fillFileRemoteUrl(filePath) {
        let result = `http://${Utils.ACUtils.localIP()}:${this.port}/api?action=file`;
        result = `${result}&path=${Urlencode.encode(filePath)}`;
        result = `${result}&stamp=${(new Date()).getTime()}`;
        return result;
    }
}
var Build;
(function (Build) {
    Build.ftp = new FTPBridge();
    function allCases(path) {
        return __awaiter(this, void 0, void 0, function* () {
            const cost = new Utils.Cost();
            const cases = new Array();
            const projects = Store.pickProjects(path);
            Utils.Console.info(`扫描可识别的工程（${projects.length}个）[${path}]`);
            let index = 1;
            let failured = 0;
            for (const root of projects) {
                Utils.Console.info(`开始构造用例[${index}/${projects.length}]`);
                index++;
                try {
                    const ptype = Store.projectType(root);
                    if (ptype === Store.ProjectType.Vue) {
                        const acase = yield vueCase(root);
                        cases.push(...acase);
                    }
                    else if (ptype === Store.ProjectType.Tiny) {
                        const acase = yield tinyCase(root);
                        cases.push(...acase);
                    }
                    else if (ptype === Store.ProjectType.Falcon) {
                        const acase = yield falconCase(root);
                        cases.push(...acase);
                    }
                    else {
                        failured++;
                    }
                }
                catch (error) {
                    Utils.Console.error(`构造用例异常: ${error} [${root}]`);
                    failured++;
                    continue;
                }
            }
            Utils.Console.info(`共成功构造用例${cases.length}个，失败${failured}个 [${path}]`);
            cost.mark();
            return Promise.resolve(cases);
        });
    }
    Build.allCases = allCases;
    function vueCase(path) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!FS.existsSync(Path.join(path, 'dist/compress/mQAppId.zip'))) {
                return Promise.reject(Error(`未找到可提取的cube编译产物`));
            }
            const cases = new Array();
            Utils.Console.info(`提取应用配置 [${Path.join(path, 'dist/app.manifest')}]`);
            const manifest = FS.existsSync(Path.join(path, 'dist/app.manifest')) ? JSON.parse(FS.readFileSync(Path.join(path, 'dist/app.manifest')).toString()) : {};
            Utils.Console.info(`提取用例配置 [${Path.join(path, 'rubik.json')}]`);
            const rbk = FS.existsSync(Path.join(path, 'rubik.json')) ? JSON.parse(FS.readFileSync(Path.join(path, 'rubik.json')).toString()) : {};
            let index = 1;
            for (const page of manifest.pages) {
                Utils.Console.info(`构建用例配置 [${page}] [${index}/${manifest.pages.length}]`);
                let acase = new Object(undefined);
                //  优先使用rubik.json内配置的字段
                if (rbk.case) {
                    acase = Object.assign({}, rbk.case);
                }
                //  追加默认处理
                if (!acase.poles) {
                    acase.poles = 'snapshot'; // 默认桩点
                }
                if (!acase.ID) {
                    acase.ID = `vue_${acase.poles}_${manifest.id}_${page}`;
                }
                else {
                    acase.ID = `vue_${acase.poles}_${acase.ID}_${page}`;
                }
                acase.ID = Urlencode.encode(acase.ID);
                if (!acase.type) {
                    acase.type = "vue";
                }
                if (!acase.subtype) {
                    acase.subtype = 'only_paint_check';
                }
                acase.iosScheme = `rubik:/launch?type=vue&dist=${urlencode_1.default(Build.ftp.fillFileRemoteUrl(Path.join(path, 'dist/compress/mQAppId.zip')))}&path=${Urlencode.encode(page)}`;
                Utils.Console.info(`创建用例配置:\n${JSON.stringify(acase, undefined, 2)}`);
                cases.push(acase);
                index++;
            }
            return Promise.resolve(cases);
        });
    }
    function falconCase(path) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!FS.existsSync(Path.join(path, 'dist'))) {
                return Promise.reject(Error(`未找到可提取的cube编译产物`));
            }
            const cases = new Array();
            Utils.Console.info(`提取工程配置 [${Path.join(path, 'package.json')}]`);
            const pkg = JSON.parse(FS.readFileSync(Path.join(path, 'package.json')).toString());
            Utils.Console.info(`提取用例配置 [${Path.join(path, 'rubik.json')}]`);
            const rbk = FS.existsSync(Path.join(path, 'rubik.json')) ? JSON.parse(FS.readFileSync(Path.join(path, 'rubik.json')).toString()) : {};
            Utils.Console.info(`清理用例构建产物 [${Path.join(path, 'dist/_rubik')}]`);
            const casePath = Path.join(path, 'dist/_rubik');
            Utils.FS.rmdirs(casePath);
            Utils.FS.mkdirs(casePath);
            let index = 1;
            Utils.FS.walk(Path.join(path, 'dist'), (root, name, stats) => {
                if (Path.extname(name) === '.bin') {
                    Utils.Console.info(`构建页面用例 [${root}] [${index}]`);
                    let manifest = JSON.parse(FS.readFileSync(Path.join(root, 'main.json')).toString());
                    manifest = JSON.parse(manifest.meta);
                    let acase = new Object(undefined);
                    //  优先使用rubik.json内配置的字段
                    if (rbk.case) {
                        acase = Object.assign({}, rbk.case);
                    }
                    //  追加默认处理
                    if (!acase.poles) {
                        acase.poles = 'snapshot'; // 默认桩点
                    }
                    if (!acase.ID) {
                        acase.ID = `falcon_${acase.poles}_${pkg.name}_${manifest.name}`;
                    }
                    else {
                        acase.ID = `falcon_${acase.poles}_${acase.ID}_${manifest.name}`;
                    }
                    acase.ID = Urlencode.encode(acase.ID);
                    if (!acase.type) {
                        acase.type = "falcon";
                    }
                    if (!acase.subtype) {
                        acase.subtype = 'only_paint_check';
                    }
                    Utils.FS.copy(root, Path.join(casePath, `${acase.ID}/dist`));
                    Utils.FS.copy(Path.join(path, 'package.json'), Path.join(casePath, `${acase.ID}/app.manifest`));
                    cases.push(acase);
                    index++;
                }
            });
            for (const acase of cases) {
                const distPath = Path.join(casePath, `${acase.ID}.zip`);
                yield Utils.FS.zip(Path.join(casePath, acase.ID), distPath);
                Utils.FS.rmdirs(Path.join(casePath, acase.ID));
                acase.iosScheme = `rubik:/launch?type=falcon&dist=${Urlencode.encode(Build.ftp.fillFileRemoteUrl(distPath))}`;
                Utils.Console.info(`创建用例配置:\n${JSON.stringify(acase, undefined, 2)}`);
            }
            return Promise.resolve(cases);
        });
    }
    function tinyCase(path) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!FS.existsSync(Path.join(path, 'dist/native'))) {
                return Promise.reject(Error(`未找到可提取的cube编译产物`));
            }
            const cases = new Array();
            Utils.Console.info(`提取工程配置 [${Path.join(path, 'dist/package/package.json')}]`);
            const pkg = JSON.parse(FS.readFileSync(Path.join(path, 'dist/package/package.json')).toString());
            Utils.Console.info(`提取应用配置 [${Path.join(path, 'dist/native/appConfig.json')}]`);
            const app = JSON.parse(FS.readFileSync(Path.join(path, 'dist/native/appConfig.json')).toString());
            Utils.Console.info(`提取用例配置 [${Path.join(path, 'rubik.json')}]`);
            const rbk = FS.existsSync(Path.join(path, 'rubik.json')) ? JSON.parse(FS.readFileSync(Path.join(path, 'rubik.json')).toString()) : {};
            let index = 1;
            const srcPath = Path.join(path, `dist/_rubik.zip`);
            Utils.FS.rmdirs(srcPath);
            yield Utils.FS.zip(Path.join(path, `dist/native`), srcPath);
            for (const page of app.pages) {
                Utils.Console.info(`构建页面用例 [${page}] [${index}/${app.pages.length}]`);
                let acase = new Object(undefined);
                //  优先使用rubik.json内配置的字段
                if (rbk.case) {
                    acase = Object.assign({}, rbk.case);
                }
                //  追加默认处理
                if (!acase.poles) {
                    acase.poles = 'snapshot'; // 默认桩点
                }
                if (!acase.ID) {
                    acase.ID = `tiny_${acase.poles}_${pkg.name}_${page}`;
                }
                else {
                    acase.ID = `tiny_${acase.poles}_${acase.ID}_${page}`;
                }
                acase.ID = Urlencode.encode(acase.ID);
                if (!acase.type) {
                    acase.type = "appx";
                }
                if (!acase.subtype) {
                    acase.subtype = 'only_paint_check';
                }
                acase.iosScheme = `rubik:/launch?type=appx&dist=${Urlencode.encode(Build.ftp.fillFileRemoteUrl(srcPath))}&path=${Urlencode.encode(page)}`;
                Utils.Console.info(`创建用例配置:\n${JSON.stringify(acase, undefined, 2)}`);
                cases.push(acase);
                index++;
            }
            return Promise.resolve(cases);
        });
    }
})(Build = exports.Build || (exports.Build = {}));
//# sourceMappingURL=build.js.map