"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.buildPreview = exports.buildProd = exports.chooseBuildPackages = exports.BuildMode = void 0;
var path = __importStar(require("path"));
var fs_1 = __importDefault(require("fs"));
var fs_extra_1 = __importDefault(require("fs-extra"));
var lodash_1 = require("lodash");
var dayjs_1 = __importDefault(require("dayjs"));
var qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
var inquirer_1 = __importDefault(require("inquirer"));
var zeppos_app_utils_1 = require("zeppos-app-utils");
var tools_1 = require("../utils/tools");
var AppType = zeppos_app_utils_1.config.AppType, getDeviceConf = zeppos_app_utils_1.config.getDeviceConf;
var appJsonPath = path.resolve('./app.json');
var appJsonContent = fs_extra_1["default"].readJSONSync(appJsonPath, { throws: false });
var BuildMode;
(function (BuildMode) {
    BuildMode["DEV"] = "development";
    BuildMode["PREVIEW"] = "preview";
    BuildMode["PROD"] = "production";
})(BuildMode = exports.BuildMode || (exports.BuildMode = {}));
var isV2ApiVersion = function (appJson) {
    var minVersion = (0, lodash_1.get)(appJson, 'runtime.apiVersion.minVersion', '');
    var minVersionArr = minVersion.split('.');
    return parseInt("0".concat(minVersionArr[0]), 10) >= 2;
};
var checkAppJson = function () {
    if (!appJsonContent) {
        try {
            fs_1["default"].accessSync(appJsonPath, fs_1["default"].constants.R_OK);
            zeppos_app_utils_1.logger.warn('Syntax error, malformed JSON in app.json file.');
        }
        catch (err) {
            zeppos_app_utils_1.logger.warn("This command needs to be executed in the root of the project.");
        }
        process.exit(1);
    }
};
var chooseBuildTargetsV3Config = function (mode, args) {
    if (mode === void 0) { mode = 'development'; }
    return __awaiter(void 0, void 0, void 0, function () {
        var target, deviceTargets, apiLevel, platforms, usefulScreenTypes, usefulDeviceSource, targetDevices, deviceNames, isValidDevice, answers, _a;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    checkAppJson();
                    target = args.target;
                    deviceTargets = getDeviceConf().deviceTargets;
                    apiLevel = (0, lodash_1.get)(appJsonContent, 'runtime.apiVersion.minVersion', '1.0.0');
                    platforms = Object.values((0, lodash_1.get)(appJsonContent, 'targets', {})).reduce(function (list, item) {
                        return list.concat((0, lodash_1.get)(item, 'platforms', []));
                    }, []);
                    usefulScreenTypes = (0, lodash_1.compact)(Object.keys((0, lodash_1.groupBy)(platforms, 'st')));
                    usefulDeviceSource = (0, lodash_1.compact)(Object.keys((0, lodash_1.groupBy)(platforms, 'deviceSource')));
                    targetDevices = {};
                    Object.values(deviceTargets).forEach(function (device) {
                        var _a;
                        var _b = device.apiLevelLimit || {}, min = _b.min, max = _b.max;
                        if (usefulScreenTypes.includes((0, lodash_1.get)(device, 'screen.type', '')) || (0, lodash_1.find)(device.platforms, function (o) { return usefulDeviceSource.includes("".concat(o.deviceSource)); })) {
                            if ((0, tools_1.compareVersion)(min || '1.0.0', apiLevel) >= 0 && max && (0, tools_1.compareVersion)(max, apiLevel) <= 0) {
                                Object.assign(targetDevices, (_a = {},
                                    _a[device.deviceName] = device,
                                    _a));
                            }
                        }
                    });
                    deviceNames = Object.keys(targetDevices);
                    if (!deviceNames.length) {
                        zeppos_app_utils_1.logger.error("The current project's API Level version is too high and there is no available device for debugging currently.");
                        process.exit(1);
                    }
                    isValidDevice = deviceNames.includes(target);
                    if (target && !isValidDevice) {
                        zeppos_app_utils_1.logger.warn("'".concat(target, "' is not a valid device, it must be one of ").concat(JSON.stringify(deviceNames)));
                    }
                    if (!isValidDevice) return [3, 1];
                    _a = { device: target };
                    return [3, 3];
                case 1: return [4, inquirer_1["default"].prompt([
                        {
                            name: 'device',
                            type: 'list',
                            message: 'Which device would you like to preview?',
                            choices: deviceNames
                        },
                    ])];
                case 2:
                    _a = _b.sent();
                    _b.label = 3;
                case 3:
                    answers = _a;
                    return [2, {
                            sources: (0, lodash_1.get)(targetDevices, "[".concat(answers.device, "].platforms"), []).reduce(function (list, item) {
                                list.push(Number(item.deviceSource));
                                return (0, lodash_1.uniq)((0, lodash_1.compact)(list));
                            }, [])
                        }];
            }
        });
    });
};
var chooseBuildTargetsV2Config = function (mode, args) {
    if (mode === void 0) { mode = 'development'; }
    return __awaiter(void 0, void 0, void 0, function () {
        var OSV2Devices, jsonTargets_1, unsupportedTargets_1, targets, returnRes, _a, promptTarget_1, answers;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    checkAppJson();
                    OSV2Devices = getDeviceConf().OSV2Devices;
                    if (isV2ApiVersion(appJsonContent)) {
                        jsonTargets_1 = (0, lodash_1.get)(appJsonContent, 'targets', {});
                        unsupportedTargets_1 = [];
                        Object.keys(jsonTargets_1).forEach(function (target) {
                            var notV2Index = (0, lodash_1.findIndex)((0, lodash_1.get)(jsonTargets_1, "".concat(target, ".platforms"), []), function (o) {
                                return !OSV2Devices.includes(o.deviceSource);
                            });
                            if (notV2Index > -1) {
                                (0, lodash_1.unset)(appJsonContent, "targets[".concat(target, "]"));
                                unsupportedTargets_1.push(target);
                            }
                        });
                        unsupportedTargets_1.length &&
                            zeppos_app_utils_1.logger.warn("Unsupported targets(".concat(unsupportedTargets_1.join(', '), ") have been removed."));
                    }
                    targets = Object.keys((0, lodash_1.get)(appJsonContent, 'targets', {}));
                    returnRes = [];
                    if (!!targets.length) return [3, 1];
                    zeppos_app_utils_1.logger.error('Please set at least one package.');
                    process.exit(1);
                    return [3, 4];
                case 1:
                    if (!(targets.length === 1)) return [3, 2];
                    returnRes = [targets[0]];
                    return [3, 4];
                case 2:
                    process.env._targetDeviceToBuild = (args === null || args === void 0 ? void 0 : args.target) || '';
                    _a = process.env._targetDeviceToBuild, promptTarget_1 = _a === void 0 ? '' : _a;
                    return [4, inquirer_1["default"].prompt([
                            {
                                name: 'target',
                                type: 'list',
                                when: function (args) {
                                    var bool = targets.includes(promptTarget_1);
                                    if (bool) {
                                        args.target = promptTarget_1;
                                    }
                                    else if (promptTarget_1) {
                                        zeppos_app_utils_1.logger.warn("'".concat(promptTarget_1, "' is not a valid target, it must be one of ").concat(JSON.stringify(targets)));
                                    }
                                    return mode !== BuildMode.PROD && !bool;
                                },
                                message: 'Which target would you like to preview?',
                                choices: targets
                            },
                            {
                                name: 'target',
                                type: 'checkbox',
                                when: function (args) {
                                    var arr = typeof promptTarget_1 === 'string'
                                        ? (0, lodash_1.intersection)(targets, promptTarget_1.split(','))
                                        : [];
                                    var bool = !!arr.length;
                                    if (bool) {
                                        args.target = arr;
                                    }
                                    return mode === BuildMode.PROD && !bool;
                                },
                                choices: targets.map(function (item) { return ({
                                    name: item,
                                    value: item,
                                    checked: true
                                }); }),
                                message: 'Which targets would you like to build?'
                            },
                        ])];
                case 3:
                    answers = _b.sent();
                    returnRes =
                        typeof answers.target === 'string' ? [answers.target] : answers.target;
                    _b.label = 4;
                case 4:
                    if (!process.env._targetDeviceToBuild) {
                        process.env._targetDeviceToBuild = returnRes[0];
                    }
                    return [2, returnRes];
            }
        });
    });
};
var chooseBuildPackages = function (mode, args) {
    if (mode === void 0) { mode = 'development'; }
    return __awaiter(void 0, void 0, void 0, function () {
        var configVersion, result, _a, sources, _b, _c, _d, _e, _f, _g;
        var _h;
        return __generator(this, function (_j) {
            switch (_j.label) {
                case 0:
                    configVersion = (0, lodash_1.toLower)((0, lodash_1.get)(appJsonContent, 'configVersion'));
                    result = {};
                    if (!(configVersion === 'v3')) return [3, 3];
                    _a = args.sources, sources = _a === void 0 ? [] : _a;
                    if (!(mode !== BuildMode.PROD && (sources.length <= 0))) return [3, 2];
                    _c = (_b = Object).assign;
                    _d = [result];
                    return [4, chooseBuildTargetsV3Config(mode, args)];
                case 1:
                    _c.apply(_b, _d.concat([_j.sent()]));
                    _j.label = 2;
                case 2: return [3, 5];
                case 3:
                    _f = (_e = Object).assign;
                    _g = [result];
                    _h = {};
                    return [4, chooseBuildTargetsV2Config(mode, args)];
                case 4:
                    _f.apply(_e, _g.concat([(_h.targets = _j.sent(),
                            _h)]));
                    _j.label = 5;
                case 5: return [2, result];
            }
        });
    });
};
exports.chooseBuildPackages = chooseBuildPackages;
var buildProd = function (args) { return __awaiter(void 0, void 0, void 0, function () {
    var _a, _b, _c, buildInfo;
    return __generator(this, function (_d) {
        switch (_d.label) {
            case 0:
                _b = (_a = Object).assign;
                _c = [args];
                return [4, (0, exports.chooseBuildPackages)(BuildMode.PROD, args)];
            case 1:
                _b.apply(_a, _c.concat([_d.sent()]));
                return [4, zeppos_app_utils_1.modules.buildSupportV3Config(path.resolve('./'), BuildMode.PROD, __assign(__assign({}, args), { renameWithAppId: (0, lodash_1.get)(appJsonContent, 'app.appId') }))];
            case 2:
                buildInfo = _d.sent();
                if (buildInfo) {
                    (0, zeppos_app_utils_1.HM_Analytics)('ZEPP_CLI_BUILD_C', { res: '1' });
                }
                else {
                    (0, zeppos_app_utils_1.HM_Analytics)('ZEPP_CLI_BUILD_C', { res: '0' });
                }
                return [2, buildInfo];
        }
    });
}); };
exports.buildProd = buildProd;
var buildPreview = function (args, callback) { return __awaiter(void 0, void 0, void 0, function () {
    var _a, curCommand, curBridgeTarget, buildMode, appType, _b, _c, _d, buildInfo;
    return __generator(this, function (_e) {
        switch (_e.label) {
            case 0:
                _a = args._, curCommand = _a[0], curBridgeTarget = _a[1];
                buildMode = curBridgeTarget && curBridgeTarget === 'simulator'
                    ? BuildMode.DEV
                    : BuildMode.PREVIEW;
                zeppos_app_utils_1.logger.info('building...');
                appType = (0, lodash_1.get)(appJsonContent, 'app.appType');
                _c = (_b = Object).assign;
                _d = [args];
                return [4, (0, exports.chooseBuildPackages)(BuildMode.PREVIEW, args)];
            case 1:
                _c.apply(_b, _d.concat([_e.sent()]));
                return [4, zeppos_app_utils_1.modules.buildSupportV3Config(path.resolve('./'), buildMode, __assign(__assign({}, args), { renameWithAppId: (0, lodash_1.get)(appJsonContent, 'app.appId') }))];
            case 2:
                buildInfo = _e.sent();
                zeppos_app_utils_1.logger.info('getting package...');
                return [4, zeppos_app_utils_1.modules
                        .previewBuild(path.resolve('./'), args, "./dist/".concat(buildInfo), appType, curCommand)
                        .then(function (res) { return __awaiter(void 0, void 0, void 0, function () {
                        return __generator(this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    if (!(res.type === 'preview')) return [3, 1];
                                    zeppos_app_utils_1.logger.info('Generating preview QR code...');
                                    zeppos_app_utils_1.logger.success("Please use Zepp APP to scan the following QR code to preview your ".concat(appType === AppType.WATCHFACE ? 'WatchFace' : 'application', "."));
                                    zeppos_app_utils_1.logger.success("The QR code will expire on ".concat((0, dayjs_1["default"])()
                                        .add(2, 'hour')
                                        .format('YYYY-MM-DD HH:mm:ss'), "."));
                                    qrcode_terminal_1["default"].generate(res.url, { small: true });
                                    callback && callback(res);
                                    return [3, 4];
                                case 1:
                                    if (!(res === 'reTry')) return [3, 3];
                                    return [4, (0, exports.buildPreview)(args)];
                                case 2:
                                    _a.sent();
                                    return [3, 4];
                                case 3:
                                    callback && callback(res);
                                    _a.label = 4;
                                case 4: return [2];
                            }
                        });
                    }); })["catch"](function () {
                        zeppos_app_utils_1.logger.error('Generating preview qrcode failed, please check your network.');
                    })];
            case 3:
                _e.sent();
                return [2];
        }
    });
}); };
exports.buildPreview = buildPreview;
