"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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 __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
exports.runX = exports.previewBuild = exports.build = exports.buildSupportV3Config = exports.BuildMode = void 0;
var zpm_1 = require("@zeppos/zpm");
var rd = __importStar(require("rd"));
var fs_1 = __importDefault(require("fs"));
var path = __importStar(require("path"));
var fs_extra_1 = __importDefault(require("fs-extra"));
var form_data_1 = __importDefault(require("form-data"));
var index_1 = require("../index");
var lodash_1 = require("lodash");
var lodash_2 = require("lodash");
var chalk_1 = __importDefault(require("chalk"));
var chokidar_1 = __importDefault(require("chokidar"));
var parse_gitignore_1 = __importDefault(require("parse-gitignore"));
var tools_1 = require("../tools/tools");
var BuildMode;
(function (BuildMode) {
    BuildMode["DEV"] = "development";
    BuildMode["PREVIEW"] = "preview";
    BuildMode["PROD"] = "production";
})(BuildMode = exports.BuildMode || (exports.BuildMode = {}));
var TransformType;
(function (TransformType) {
    TransformType["Default"] = "";
    TransformType["Js"] = "js";
    TransformType["C"] = "c";
    TransformType["Bin"] = "bin";
})(TransformType || (TransformType = {}));
var INNER_PRODUCT_TIP = "\n\n".concat(chalk_1["default"].yellow.bold('Notice:'), "\n").concat(chalk_1["default"].blue('Please note that if your installation package includes intermediate products, you specifically authorize us to modify, edit, utilize, repackage, and distribute the installation package(including intermediate products) for the following purposes:'), "\n\n").concat(chalk_1["default"].blue.bold('1.'), " Using intermediate products to generate new installation packages and distribute them to new devices;\n").concat(chalk_1["default"].blue.bold('2.'), " Distribute the installation package to devices with the same CPU architecture and screen resolution, not limited to the device you have currently selected.\n\nHowever, we will not distribute intermediate products to user devices directly. If you choose not to include intermediate products in your installation package, use the ").concat(chalk_1["default"].bold.green('zeus prune --ip'), " command to remove it immediately after the build is completed. However, you\u2019ll then have to manually provide a build for each device type.\n\n");
var gitignoreDefaultItem = [
    '.DS_Store',
    'node_modules/**',
    'dist/*',
    'npm-debug.log',
    'yarn-debug.log*',
    'yarn-error.log*',
    'yarn.lock',
    'package-lock.json',
    'selenium-debug.log',
    '.idea',
    '.vscode',
    '*.suo',
    '*.ntvs*',
    '*.njsproj',
    '*.sln',
];
var buildSupportV3Config = function (workspace, mode, buildConfigOption) {
    if (mode === void 0) { mode = BuildMode.PROD; }
    if (buildConfigOption === void 0) { buildConfigOption = {}; }
    return __awaiter(void 0, void 0, void 0, function () {
        var _a, sources_1, _b, targets, _c, sources, buildOptions, _d, js2c, _e, js2bin, _f, png2vg, _g, prune, _h, compress, _j, ip, zabName_1, distDir_1, name_1, newName_1, error_1;
        return __generator(this, function (_k) {
            switch (_k.label) {
                case 0:
                    if (buildConfigOption.sources) {
                        _a = buildConfigOption.sources, sources_1 = _a === void 0 ? [] : _a;
                        buildConfigOption = __assign(__assign({}, buildConfigOption), { sources: Array.isArray(sources_1) ? sources_1 : [sources_1] });
                    }
                    _b = buildConfigOption.targets, targets = _b === void 0 ? [] : _b, _c = buildConfigOption.sources, sources = _c === void 0 ? [] : _c;
                    buildOptions = {
                        path: workspace,
                        buildMode: mode,
                        targets: targets,
                        sources: sources,
                        jsc: TransformType.Default
                    };
                    if ([BuildMode.PROD, BuildMode.PREVIEW].includes(mode)) {
                        _d = buildConfigOption || {}, js2c = _d.js2c, _e = _d.js2bin, js2bin = _e === void 0 ? true : _e, _f = _d.png2vg, png2vg = _f === void 0 ? true : _f, _g = _d.prune, prune = _g === void 0 ? true : _g, _h = _d.compress, compress = _h === void 0 ? true : _h, _j = _d.ip, ip = _j === void 0 ? BuildMode.PROD === mode : _j;
                        js2c = (0, tools_1.booleanString)(js2c);
                        js2bin = (0, tools_1.booleanString)(js2bin);
                        js2c && Object.assign(buildOptions, { jsc: TransformType.C });
                        js2bin && Object.assign(buildOptions, { jsc: TransformType.Bin });
                        Object.assign(buildOptions, {
                            png2vg: (0, tools_1.booleanString)(png2vg),
                            prune: (0, tools_1.booleanString)(prune),
                            compress: (0, tools_1.booleanString)(compress),
                            ip: (0, tools_1.booleanString)(ip)
                        });
                    }
                    _k.label = 1;
                case 1:
                    _k.trys.push([1, 6, , 7]);
                    if (targets.length) {
                        index_1.logger.info("Start building package, targets: ".concat(targets.join(', '), "."));
                    }
                    else if (sources.length) {
                        index_1.logger.info("Start building package, device sources: ".concat(sources.join(', '), "."));
                    }
                    if (!(mode === BuildMode.DEV && (0, lodash_1.get)(buildConfigOption, '_[0]') !== 'install')) return [3, 3];
                    return [4, (0, zpm_1.startWithoutDist)(buildOptions)];
                case 2: return [2, _k.sent()];
                case 3: return [4, (0, zpm_1.start)(buildOptions)];
                case 4:
                    zabName_1 = _k.sent();
                    if (!zabName_1) {
                        index_1.logger.error("Build package error, the package name is ".concat(zabName_1));
                        process.exit(1);
                    }
                    if (buildConfigOption.renameWithAppId) {
                        distDir_1 = path.join(workspace, 'dist');
                        name_1 = zabName_1.replace(/[\s]/g, '_').split('.zab');
                        newName_1 = "".concat(buildConfigOption.renameWithAppId, "-").concat(name_1[0], ".zab");
                        rd.eachFileSync(distDir_1, function (file) {
                            var oldName = path.join(distDir_1, zabName_1);
                            if (file !== oldName) {
                                fs_extra_1["default"].removeSync(file);
                            }
                            else {
                                fs_1["default"].renameSync(oldName, path.join(distDir_1, newName_1));
                            }
                        });
                        mode === BuildMode.PROD && index_1.logger.log(INNER_PRODUCT_TIP);
                        return [2, newName_1];
                    }
                    return [2, zabName_1];
                case 5: return [3, 7];
                case 6:
                    error_1 = _k.sent();
                    index_1.logger.error(error_1);
                    return [3, 7];
                case 7: return [2];
            }
        });
    });
};
exports.buildSupportV3Config = buildSupportV3Config;
var build = function (workspace, mode, buildConfigOption, packages, appId) {
    if (mode === void 0) { mode = BuildMode.PROD; }
    if (appId === void 0) { appId = '10000'; }
    return __awaiter(void 0, void 0, void 0, function () {
        var buildOptions, _a, js2c, _b, js2bin, _c, png2vg, _d, prune, _e, compress, _f, ip, curOpt, productName_1, DistDir_1, name_2, newName_2, error_2;
        return __generator(this, function (_g) {
            switch (_g.label) {
                case 0:
                    buildOptions = {
                        path: workspace,
                        targets: packages,
                        buildMode: mode,
                        jsc: TransformType.Default
                    };
                    if (mode === BuildMode.PROD || mode === BuildMode.PREVIEW) {
                        _a = buildConfigOption || {}, js2c = _a.js2c, _b = _a.js2bin, js2bin = _b === void 0 ? true : _b, _c = _a.png2vg, png2vg = _c === void 0 ? true : _c, _d = _a.prune, prune = _d === void 0 ? true : _d, _e = _a.compress, compress = _e === void 0 ? true : _e, _f = _a.ip, ip = _f === void 0 ? (mode === BuildMode.PROD) : _f;
                        js2c = (0, tools_1.booleanString)(js2c);
                        js2bin = (0, tools_1.booleanString)(js2bin);
                        js2c && Object.assign(buildOptions, { jsc: TransformType.C });
                        js2bin && Object.assign(buildOptions, { jsc: TransformType.Bin });
                        Object.assign(buildOptions, {
                            png2vg: (0, tools_1.booleanString)(png2vg),
                            prune: (0, tools_1.booleanString)(prune),
                            compress: (0, tools_1.booleanString)(compress),
                            ip: (0, tools_1.booleanString)(ip)
                        });
                    }
                    _g.label = 1;
                case 1:
                    _g.trys.push([1, 6, , 7]);
                    index_1.logger.info("Start building package, targets: ".concat(packages.join(', '), "."));
                    curOpt = (0, lodash_1.get)(buildConfigOption, '_', [])[0];
                    if (!(mode !== BuildMode.DEV ||
                        (mode === BuildMode.DEV && curOpt === 'install'))) return [3, 3];
                    return [4, (0, zpm_1.start)(buildOptions)];
                case 2:
                    productName_1 = _g.sent();
                    if (productName_1) {
                        DistDir_1 = path.join(workspace, 'dist');
                        name_2 = productName_1.replace(/[\s]/g, '_').split('.zab');
                        newName_2 = "".concat(appId, "-").concat(name_2[0], ".zab");
                        rd.eachFileSync(DistDir_1, function (file) {
                            var oldName = path.join(DistDir_1, productName_1);
                            if (file !== oldName) {
                                fs_extra_1["default"].removeSync(file);
                            }
                            else {
                                fs_1["default"].renameSync(oldName, path.join(DistDir_1, newName_2));
                            }
                        });
                        productName_1 = newName_2;
                    }
                    return [2, productName_1];
                case 3:
                    if (!(mode === BuildMode.DEV)) return [3, 5];
                    return [4, (0, zpm_1.startWithoutDist)(buildOptions)];
                case 4:
                    _g.sent();
                    return [2, (0, zpm_1.getZpkBuf)(packages[0])];
                case 5: return [3, 7];
                case 6:
                    error_2 = _g.sent();
                    index_1.logger.error(error_2);
                    return [3, 7];
                case 7: return [2];
            }
        });
    });
};
exports.build = build;
var previewBuild = function (root, args, workspace, appType, curCommand) { return __awaiter(void 0, void 0, void 0, function () {
    return __generator(this, function (_a) {
        return [2, new Promise(function (resolve, reject) { return __awaiter(void 0, void 0, void 0, function () {
                var form;
                return __generator(this, function (_a) {
                    form = new form_data_1["default"]();
                    form.append('file', fs_1["default"].createReadStream(workspace));
                    form.append('app_type', appType === index_1.config.AppType.WATCHFACE ? '1' : '2');
                    form.getLength(function (err, length) { return __awaiter(void 0, void 0, void 0, function () {
                        var protocol, code, res, error_3, _subRegionalHost, url, _a, deviceSource, appId, appName, appType_1, deviceSourceArr, targetDeviceInternalName, packageInfo, url, preview, downloadPackageReturn;
                        return __generator(this, function (_b) {
                            switch (_b.label) {
                                case 0:
                                    if (err) {
                                        index_1.logger.error('getting package failed.');
                                        return [2];
                                    }
                                    protocol = '';
                                    code = '';
                                    _b.label = 1;
                                case 1:
                                    _b.trys.push([1, 3, , 7]);
                                    return [4, index_1.api.uploadPackage(form, length)];
                                case 2:
                                    res = _b.sent();
                                    protocol = res.protocol;
                                    code = res.code;
                                    return [3, 7];
                                case 3:
                                    error_3 = _b.sent();
                                    if (!((error_3 === null || error_3 === void 0 ? void 0 : error_3.message) === '401')) return [3, 5];
                                    index_1.logger.warn("Login information is invalid. Please login again, or end this service and login again with the command 'zeus login'.");
                                    return [4, index_1.modules.login().then(function (res) { return __awaiter(void 0, void 0, void 0, function () {
                                            return __generator(this, function (_a) {
                                                args._loginAppToken = res.appToken;
                                                process.env._loginAppToken = res.appToken;
                                                reject('reTry');
                                                return [2];
                                            });
                                        }); })];
                                case 4:
                                    _b.sent();
                                    return [3, 6];
                                case 5:
                                    index_1.logger.error(error_3 === null || error_3 === void 0 ? void 0 : error_3.message);
                                    reject('reTry');
                                    return [2];
                                case 6: return [3, 7];
                                case 7:
                                    if (!(curCommand === 'preview')) return [3, 8];
                                    _subRegionalHost = process.env._subRegionalHost;
                                    url = "".concat(protocol, "://").concat(_subRegionalHost, "/custom/tools/app-dial/download/").concat(code);
                                    protocol && code ? resolve({ type: 'preview', url: url }) : reject();
                                    return [3, 10];
                                case 8:
                                    if (!(curCommand === 'install')) return [3, 10];
                                    _a = (0, index_1.getDeviceInfoFromAppJson)(root), deviceSource = _a.deviceSource, appId = _a.appId, appName = _a.appName, appType_1 = _a.appType, deviceSourceArr = _a.deviceSourceArr, targetDeviceInternalName = _a.targetDeviceInternalName;
                                    return [4, index_1.api.downloadPackage(code, (0, lodash_1.get)(args, "sources[0]", deviceSource), appType_1)];
                                case 9:
                                    packageInfo = _b.sent();
                                    url = packageInfo;
                                    preview = '';
                                    if (appType_1 === index_1.config.AppType.WATCHFACE) {
                                        downloadPackageReturn = (0, lodash_1.get)(packageInfo, 'data', {});
                                        url = downloadPackageReturn.url;
                                        preview = downloadPackageReturn.preview;
                                    }
                                    resolve({
                                        appType: appType_1,
                                        url: url,
                                        preview: preview,
                                        appid: appId,
                                        name: appName,
                                        "debugger": true,
                                        updatedTime: Math.round(new Date().getTime() / 1000),
                                        devices: (0, lodash_1.get)(args, "sources", deviceSourceArr),
                                        target: targetDeviceInternalName
                                    });
                                    _b.label = 10;
                                case 10: return [2];
                            }
                        });
                    }); });
                    return [2];
                });
            }); })];
    });
}); };
exports.previewBuild = previewBuild;
var runX = function (root, args, url, logAfterFunc) { return __awaiter(void 0, void 0, void 0, function () {
    var logger, simulator, refreshSimulator, gitignorePath, gitignore, ignored;
    return __generator(this, function (_a) {
        logger = new index_1.MyLogger();
        if (logAfterFunc) {
            logger.addAfterFunc(logAfterFunc);
        }
        simulator = new index_1.Simulator(url);
        refreshSimulator = (0, lodash_2.debounce)(function () { return __awaiter(void 0, void 0, void 0, function () {
            var zpkBuffer, _a, targetDeviceInternalName, appId, devices, projectName;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        logger.info('rebuilding...');
                        return [4, (0, exports.buildSupportV3Config)(root, BuildMode.DEV, args)];
                    case 1:
                        zpkBuffer = _b.sent();
                        if (zpkBuffer) {
                            logger.info('rebuild done');
                            logger.info('refreshing simulator...');
                            _a = (0, index_1.getDeviceInfoFromAppJson)(root), targetDeviceInternalName = _a.targetDeviceInternalName, appId = _a.appId, devices = _a.deviceSourceArr;
                            projectName = path.parse(process.cwd()).base;
                            simulator.upload(zpkBuffer, projectName, targetDeviceInternalName, appId, devices);
                        }
                        else {
                            logger.error('build error');
                        }
                        logger.info(chalk_1["default"].green("watching the changes in this project..."));
                        return [2];
                }
            });
        }); }, 150, { maxWait: 1000 });
        refreshSimulator();
        gitignorePath = path.resolve(root, '.gitignore');
        fs_extra_1["default"].ensureFileSync(gitignorePath);
        gitignore = (0, parse_gitignore_1["default"])(fs_extra_1["default"].readFileSync(gitignorePath));
        if (!gitignore.length) {
            fs_extra_1["default"].writeFileSync(gitignorePath, gitignoreDefaultItem.join('\n'));
            gitignore = gitignoreDefaultItem;
        }
        ignored = (0, lodash_2.union)([
            '.gitignore',
            'jsconfig.json',
            'dist/**/*',
            'dist',
            'node_modules/**',
            'node_modules',
            '.git/**',
            'yarn.lock',
            'package-lock.json',
        ], gitignore);
        return [2, chokidar_1["default"]
                .watch('.', {
                ignored: ignored,
                ignoreInitial: true,
                interval: 1000,
                cwd: root
            })
                .on('all', function (_type, path) {
                logger.info("".concat(path, " ").concat(chalk_1["default"].green(_type)));
                path && refreshSimulator();
            })];
    });
}); };
exports.runX = runX;
