"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDeviceConf = exports.DeviceScreenType = void 0;
var lodash_1 = require("lodash");
var tweetnacl_util_1 = require("tweetnacl-util");
var tweetnacl_1 = require("tweetnacl");
var path_1 = __importDefault(require("path"));
var os_1 = __importDefault(require("os"));
var fs_1 = __importDefault(require("fs"));
var fs_extra_1 = __importDefault(require("fs-extra"));
var tools_1 = require("../tools/tools");
var LOCAL_CACHE_DEVICE_PATH = path_1.default.resolve(os_1.default.homedir(), ".zepp/.zeus_devices");
var pkgInfo = require(path_1.default.join(__dirname, '../../package.json'));
var isBeta = pkgInfo.dependencies['@zeppos/zpm'].indexOf('-beta') !== -1;
var u8Array = function (str) { return new Uint8Array(str.split(',').map(function (s) { return parseInt(s, 10); })); };
var sharedKey = '18,53,81,26,124,228,216,202,47,58,73,19,245,186,86,169,180,116,161,250,36,203,127,120,133,126,203,121,143,100,17,44';
var decrypt = function (str, key) {
    var messageWithNonceAsUint8Array = (0, tweetnacl_util_1.decodeBase64)(str);
    var nonce = messageWithNonceAsUint8Array.slice(0, tweetnacl_1.box.nonceLength);
    var message = messageWithNonceAsUint8Array.slice(tweetnacl_1.box.nonceLength, str.length);
    var decrypted = tweetnacl_1.box.open.after(message, nonce, key);
    if (!decrypted) {
        throw new Error('Could not decrypt message');
    }
    return (0, tweetnacl_util_1.encodeUTF8)(decrypted);
};
var DeviceScreenType;
(function (DeviceScreenType) {
    DeviceScreenType["R"] = "r";
    DeviceScreenType["S"] = "s";
    DeviceScreenType["B"] = "b";
})(DeviceScreenType || (exports.DeviceScreenType = DeviceScreenType = {}));
var shapeMap = {
    square: DeviceScreenType.S,
    round: DeviceScreenType.R,
    bar: DeviceScreenType.B,
};
function getDeviceList(localContent) {
    var deviceChannel = isBeta ? 'devices_beta' : 'devices';
    var deviceList = (0, lodash_1.get)(localContent, deviceChannel, []);
    if (!isBeta)
        return deviceList;
    return deviceList.map(function (d) { return JSON.parse(decrypt(d, u8Array(sharedKey))); });
}
function getDeviceInfo() {
    var localContent = {};
    if (fs_1.default.existsSync(LOCAL_CACHE_DEVICE_PATH)) {
        try {
            localContent = fs_extra_1.default.readJsonSync(LOCAL_CACHE_DEVICE_PATH);
        }
        catch (_e) { }
    }
    var deviceList = getDeviceList(localContent);
    var deviceGroup = (0, lodash_1.groupBy)(deviceList, 'productName');
    var deviceInfo = {};
    Object.values(deviceGroup).forEach(function (devices) {
        var _a;
        var info = {
            deviceName: '',
            platforms: [],
            screen: {
                type: DeviceScreenType.R,
                width: 0,
                height: 0,
            },
            apiLevelLimit: {
                min: '1.0.0',
            },
        };
        var deviceInnerName = devices.reduce(function (acc, cur) {
            !info.deviceName && (info.deviceName = cur.productName);
            var screenType = (0, lodash_1.get)(shapeMap, (0, lodash_1.get)(cur, 'value.shape'));
            var _a = (0, lodash_1.get)(cur, 'value.screen.size', '').split('*'), width = _a[0], height = _a[1];
            if (screenType) {
                info.screen.type = screenType;
            }
            if (width && height) {
                info.screen.width = Number(width);
                info.screen.height = Number(height);
            }
            info.platforms.push({
                name: cur.code,
                deviceSource: cur.deviceSource,
            });
            Object.assign(info.apiLevelLimit, {
                min: (0, lodash_1.get)(cur, 'value.os.apiLevelLimitMin', '1.0.0'),
                max: (0, lodash_1.get)(cur, 'value.os.apiLevel', '') || (0, lodash_1.get)(cur, 'value.os.apiLevelLimitMax'),
            });
            return cur.code.length < acc.length ? cur.code : acc;
        }, devices[0].code);
        var lowerName = (0, lodash_1.toLower)(deviceInnerName.replace(/[^a-zA-Z]/g, ''));
        lowerName &&
            Object.assign(deviceInfo, (_a = {},
                _a[lowerName] = info,
                _a));
    });
    return deviceInfo;
}
var getDeviceConf = function () {
    var deviceTargets = getDeviceInfo();
    var OSV2Devices = Object.values(deviceTargets).reduce(function (targetDevices, target) {
        var _a = target.platforms, platforms = _a === void 0 ? [] : _a, _b = target.apiLevelLimit, apiLevelLimit = _b === void 0 ? {} : _b;
        var min = apiLevelLimit.min, max = apiLevelLimit.max;
        if (!(0, lodash_1.isEmpty)(platforms) &&
            (0, tools_1.compareVersion)(min || '1.0.0', '2.0.0') >= 0 &&
            max &&
            (0, tools_1.compareVersion)(max, '2.0.0') <= 0) {
            targetDevices.push.apply(targetDevices, platforms.reduce(function (list, o) { return (0, lodash_1.compact)(list.concat([o.deviceSource])); }, []));
        }
        return targetDevices;
    }, []);
    var OSV2DeviceTargetNames = Object.keys(deviceTargets).reduce(function (targetNames, target) {
        var flag = true;
        var _a = deviceTargets[target].platforms, platforms = _a === void 0 ? [] : _a;
        if (platforms && platforms.length) {
            platforms.forEach(function (_a) {
                var deviceSource = _a.deviceSource;
                if (!OSV2Devices.includes(deviceSource)) {
                    flag = false;
                }
            });
        }
        else {
            flag = false;
        }
        flag && targetNames.push(target);
        return targetNames;
    }, []);
    var deviceInternalCodeName = Object.keys(deviceTargets).reduce(function (deviceSources, target) {
        var _a = deviceTargets[target].platforms, platforms = _a === void 0 ? [] : _a;
        platforms.forEach(function (_a) {
            var deviceSource = _a.deviceSource;
            deviceSource && (deviceSources[deviceSource] = target);
        });
        return deviceSources;
    }, {});
    return {
        deviceTargets: deviceTargets,
        OSV2Devices: OSV2Devices,
        OSV2DeviceTargetNames: OSV2DeviceTargetNames,
        deviceInternalCodeName: deviceInternalCodeName,
    };
};
exports.getDeviceConf = getDeviceConf;
