"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.killChildProcess = exports.startChrome = exports.startIWDP = exports.startTunnel = exports.tunnelEmitter = exports.TUNNEL_EVENT = void 0;
const tslib_1 = require("tslib");
const child_process_1 = require("child_process");
const events_1 = require("events");
const path_1 = tslib_1.__importDefault(require("path"));
const os_1 = tslib_1.__importDefault(require("os"));
const open_1 = tslib_1.__importDefault(require("open"));
const enum_1 = require("@/@types/enum");
const device_manager_1 = require("@/device-manager");
const log_1 = require("@/utils/log");
const config_1 = require("@/config");
const adb_1 = require("./adb");
const childProcessLog = new log_1.Logger('child-process', enum_1.WinstonColor.Magenta);
const tunnelLog = new log_1.TunnelLogger('tunnel', enum_1.WinstonColor.BrightRed);
let proxyProcess;
exports.TUNNEL_EVENT = 'message';
exports.tunnelEmitter = new events_1.EventEmitter();
const startTunnel = (cb) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    global.addon.addEventListener((event, data) => {
        var _a;
        try {
            if (event !== "tunnel_log" /* TunnelLog */) {
                tunnelLog.info('tunnel event: %s', event);
            }
            if (event === "tunnel_recv_data" /* ReceiveData */) {
                exports.tunnelEmitter.emit(exports.TUNNEL_EVENT, data);
            }
            else {
                if (["tunnel_remove_device" /* RemoveDevice */, "tunnel_add_device" /* AddDevice */].indexOf(event) !== -1) {
                    device_manager_1.deviceManager.getDeviceList();
                    if (event === "tunnel_add_device" /* AddDevice */) {
                        // 每次设备连接后，运行 adb reverse
                        adb_1.startAdbProxy();
                    }
                }
                else if (event === "tunnel_app_connect" /* AppConnect */) {
                    device_manager_1.deviceManager.onAppConnect();
                }
                else if (event === "tunnel_app_disconnect" /* AppDisconnect */) {
                    device_manager_1.deviceManager.onAppDisconnect();
                }
                else if (event === "tunnel_log" /* TunnelLog */ && data) {
                    tunnelLog.verbose(data);
                }
                if (cb)
                    cb(event, data);
            }
        }
        catch (e) {
            tunnelLog.error('handle tunnel event error: %s', (_a = e) === null || _a === void 0 ? void 0 : _a.stack);
        }
    });
    global.addon.tunnelStart(getTunnelOption());
});
exports.startTunnel = startTunnel;
const startIWDP = () => {
    const { iWDPPort } = global.debugAppArgv;
    const { iWDPStartPort, iWDPEndPort } = config_1.config;
    proxyProcess = child_process_1.spawn('ios_webkit_debug_proxy', ['--no-frontend', `--config=null:${iWDPPort},:${iWDPStartPort}-${iWDPEndPort}`], { detached: false });
    proxyProcess.unref();
    childProcessLog.info(`start IWDP on port ${iWDPPort}`);
    proxyProcess.stdout.on('data', (msg) => childProcessLog.info(msg.toString()));
    proxyProcess.stderr.on('data', (msg) => childProcessLog.error(msg.toString()));
    proxyProcess.on('error', (e) => {
        childProcessLog.error('IWDP error: %s', e === null || e === void 0 ? void 0 : e.stack);
    });
    proxyProcess.on('message', (msg) => {
        childProcessLog.info('IWDP message: %j', msg);
    });
    proxyProcess.on('close', (code) => {
        childProcessLog.warn(`IWDP close with code: ${code}`);
    });
};
exports.startIWDP = startIWDP;
const startChrome = () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
    var _a;
    const { open: openChrome } = global.debugAppArgv;
    if (openChrome) {
        const url = `${config_1.config.domain}/extensions/home.html`;
        try {
            open_1.default(url, { app: { name: open_1.default.apps.chrome } });
        }
        catch (e) {
            childProcessLog.error('open %s by chrome failed, please open manually, %s', url, (_a = e) === null || _a === void 0 ? void 0 : _a.stack);
        }
    }
});
exports.startChrome = startChrome;
const killChildProcess = () => {
    if (!proxyProcess)
        return;
    childProcessLog.warn('on log.info server exit, do some clean...');
    proxyProcess === null || proxyProcess === void 0 ? void 0 : proxyProcess.kill('SIGKILL');
    proxyProcess = null;
};
exports.killChildProcess = killChildProcess;
function getTunnelOption() {
    const { iWDPPort, log } = global.debugAppArgv;
    const { iWDPStartPort, iWDPEndPort } = config_1.config;
    const iWDPParams = [
        '--no-frontend',
        log === enum_1.LogLevel.Silly ? '--debug' : '',
        `--config=null:${iWDPPort},:${iWDPStartPort}-${iWDPEndPort}`,
    ].filter(Boolean);
    let tunnelOption;
    if (os_1.default.type() === enum_1.OSType.Darwin) {
        tunnelOption = {
            adb_path: path_1.default.join(__dirname, '../build/mac/adb'),
            iwdp: {
                iwdp_params: iWDPParams,
                iwdp_listen_port: iWDPPort,
            },
            only_use_iwdp: 0,
        };
    }
    if (os_1.default.type() === enum_1.OSType.Windows) {
        tunnelOption = {
            adb_path: path_1.default.join(__dirname, '../build/win/adb.exe'),
            iwdp: {
                iwdp_params: iWDPParams,
                iwdp_listen_port: iWDPPort,
                iwdp_path: path_1.default.join(__dirname, '../build/win/iwdp1.8.8/ios_webkit_debug_proxy.exe'),
            },
            only_use_iwdp: 0,
            iproxy_path: path_1.default.join(__dirname, '../build/win/idevice/iproxy.exe'),
            idevice_info_path: path_1.default.join(__dirname, '../build/win/idevice/ideviceinfo.exe'),
        };
    }
    childProcessLog.info('tunnel option: %j', tunnelOption);
    return tunnelOption;
}
