"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeDebugTarget = exports.decreaseRefAndSave = exports.patchRefAndSave = exports.wsUrlWithoutProtocol = exports.patchDebugTarget = exports.createTargetByIWDPPage = exports.createTargetByWsUrlParams = exports.createTargetByDeviceInfo = void 0;
const tslib_1 = require("tslib");
const enum_1 = require("@/@types/enum");
const url_1 = require("@/utils/url");
const config_1 = require("@/config");
const iwdp_1 = require("@/utils/iwdp");
const db_1 = require("@/db");
const log_1 = require("@/utils/log");
const log = new log_1.Logger('debug-target-util');
/**
 * 通过 device 信息创建调试对象
 */
const createTargetByDeviceInfo = (device) => {
    // 通过 tunnel 创建的 target，暂时使用 devicename 作为调试对象 id，后续终端重构后使用 targetCreated 事件抛出的 id
    const clientId = device.devicename;
    const wsUrl = url_1.makeUrl(`${config_1.config.wsDomain}${config_1.config.wsPath}`, {
        clientId,
        role: enum_1.ClientRole.Devtools,
    });
    const devtoolsFrontendUrl = url_1.makeUrl(`${config_1.config.domain}/front_end/inspector.html`, {
        remoteFrontend: true,
        experiments: true,
        [config_1.config.wsProtocol]: wsUrlWithoutProtocol(wsUrl),
        env: global.debugAppArgv.env,
    });
    const title = device.platform === enum_1.DevicePlatform.IOS ? clientId : 'Hippy debug tools for V8';
    return {
        clientId,
        devtoolsFrontendUrl,
        thumbnailUrl: '',
        title,
        url: '',
        description: '',
        webSocketDebuggerUrl: wsUrl,
        platform: device.platform,
        type: enum_1.ChromePageType.Page,
        appClientTypeList: ["TunnelAppClient" /* Tunnel */],
        deviceId: device.deviceid,
        deviceName: device.devicename,
        deviceOSVersion: device.osVersion,
        ref: 1,
    };
};
exports.createTargetByDeviceInfo = createTargetByDeviceInfo;
/**
 * 通过 ws 连接 url 创建调试对象
 */
const createTargetByWsUrlParams = (wsUrlParams) => {
    const { clientId, clientRole, contextName, deviceName, hash } = wsUrlParams;
    let platform;
    if (clientRole === enum_1.ClientRole.Android)
        platform = enum_1.DevicePlatform.Android;
    if (clientRole === enum_1.ClientRole.IOS)
        platform = enum_1.DevicePlatform.IOS;
    const wsUrl = url_1.makeUrl(`${config_1.config.wsDomain}${config_1.config.wsPath}`, {
        clientId,
        role: enum_1.ClientRole.Devtools,
        hash,
    });
    const devtoolsFrontendUrl = url_1.makeUrl(`${config_1.config.domain}/front_end/inspector.html`, {
        remoteFrontend: true,
        experiments: true,
        [config_1.config.wsProtocol]: wsUrlWithoutProtocol(wsUrl),
        env: global.debugAppArgv.env,
        hash,
    });
    return {
        hash,
        clientId,
        devtoolsFrontendUrl,
        thumbnailUrl: '',
        title: contextName,
        url: '',
        description: '',
        webSocketDebuggerUrl: wsUrl,
        platform,
        type: enum_1.ChromePageType.Page,
        deviceName,
        appClientTypeList: ["WSAppClient" /* WS */],
        ref: 1,
    };
};
exports.createTargetByWsUrlParams = createTargetByWsUrlParams;
/**
 * 通过 IWDP 获取到的页面创建调试对象
 */
const createTargetByIWDPPage = (iWDPPage) => {
    const iWDPWsUrl = iWDPPage.webSocketDebuggerUrl;
    const wsUrl = url_1.makeUrl(`${config_1.config.wsDomain}${config_1.config.wsPath}`, {
        clientId: iWDPWsUrl,
        role: enum_1.ClientRole.Devtools,
    });
    const devtoolsFrontendUrl = url_1.makeUrl(`${config_1.config.domain}/front_end/inspector.html`, {
        remoteFrontend: true,
        experiments: true,
        [config_1.config.wsProtocol]: wsUrlWithoutProtocol(wsUrl),
        env: global.debugAppArgv.env,
    });
    return {
        clientId: iWDPWsUrl,
        iWDPWsUrl,
        devtoolsFrontendUrl,
        title: iWDPPage.title,
        thumbnailUrl: '',
        url: '',
        description: '',
        webSocketDebuggerUrl: wsUrl,
        platform: enum_1.DevicePlatform.IOS,
        type: enum_1.ChromePageType.Page,
        deviceId: iWDPPage.device.deviceId,
        deviceName: iWDPPage.device.deviceName,
        deviceOSVersion: iWDPPage.device.deviceOSVersion,
        appClientTypeList: ["IWDPAppClient" /* IWDP */],
        ref: 1,
    };
};
exports.createTargetByIWDPPage = createTargetByIWDPPage;
/**
 * 补充完整 debugTarget 信息。
 * 当 iOS 根据 device 创建出调试对象时，用 IWDP 获取到的额外信息加以补充
 */
const patchDebugTarget = (debugTarget) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    if (debugTarget.platform === enum_1.DevicePlatform.IOS) {
        const iOSPages = yield iwdp_1.getIWDPPages(global.debugAppArgv.iWDPPort);
        return iwdp_1.patchIOSTarget(debugTarget, iOSPages);
    }
    return debugTarget;
});
exports.patchDebugTarget = patchDebugTarget;
function wsUrlWithoutProtocol(wsUrl) {
    return wsUrl.replace('wss://', '').replace('ws://', '');
}
exports.wsUrlWithoutProtocol = wsUrlWithoutProtocol;
const patchRefAndSave = (newDebugTarget) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    const { DB } = db_1.getDBOperator();
    const { clientId } = newDebugTarget;
    const db = new DB(config_1.config.redis.debugTargetTable);
    const oldDebugTarget = yield db.get(clientId);
    const debugTarget = newDebugTarget;
    if (oldDebugTarget) {
        debugTarget.ref = oldDebugTarget.ref + 1;
        log.info('increase debugTarget ref, clientId: %s, ref: %s', clientId, debugTarget.ref);
    }
    const patched = yield exports.patchDebugTarget(debugTarget);
    yield db.upsert(clientId, patched);
    return patched;
});
exports.patchRefAndSave = patchRefAndSave;
const decreaseRefAndSave = (clientId) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    const { DB } = db_1.getDBOperator();
    const db = new DB(config_1.config.redis.debugTargetTable);
    const debugTarget = yield db.get(clientId);
    if (!debugTarget)
        return;
    debugTarget.ref -= 1;
    log.info('decrease debugTarget ref, clientId: %s, ref: %s', clientId, debugTarget.ref);
    if (debugTarget.ref <= 0) {
        db.delete(clientId);
        log.info('debugTarget ref is 0, should delete, clientId: %s', clientId);
        return;
    }
    yield db.upsert(clientId, debugTarget);
    return debugTarget;
});
exports.decreaseRefAndSave = decreaseRefAndSave;
const removeDebugTarget = (clientId) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    const { DB } = db_1.getDBOperator();
    const db = new DB(config_1.config.redis.debugTargetTable);
    return db.delete(clientId);
});
exports.removeDebugTarget = removeDebugTarget;
