"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runApp = void 0;
const tslib_1 = require("tslib");
const child_process_1 = tslib_1.__importStar(require("child_process"));
const fs_1 = tslib_1.__importDefault(require("fs"));
const prompts_1 = tslib_1.__importDefault(require("prompts"));
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const utils_1 = require("./utils");
const buildIos_1 = require("./buildIos");
const iosUtils_1 = require("./iosUtils");
const path_1 = tslib_1.__importDefault(require("path"));
const config_1 = require("./config");
const logger_1 = tslib_1.__importDefault(require("./logger"));
function getDevices() {
    const devicesJson = JSON.parse(child_process_1.default.execSync('xcrun simctl list -j devices', { encoding: 'utf-8' }));
    return Object.values(devicesJson.devices).flat();
}
function getBootedDevices(allDevices) {
    return allDevices.filter(d => d.state === 'Booted');
}
function checkBuildPresent(buildType, target) {
    const { destination } = (0, iosUtils_1.getIosBuildDestination)(target, buildType);
    return fs_1.default.existsSync(destination);
}
function installApp(deviceUdid, buildType, target) {
    const { destination } = (0, iosUtils_1.getIosBuildDestination)(target, buildType);
    const res = child_process_1.default.execSync(`xcrun simctl install ${deviceUdid} ${destination}`, { encoding: 'utf-8' });
    console.log('res', res);
}
function launchApp(deviceUid, bundleId) {
    child_process_1.default.execSync(`xcrun simctl launch ${deviceUid} ${bundleId}`);
}
function isErrorWithStderr(e) {
    if (typeof e === 'object' && e !== null && 'stderr' in e) {
        return typeof e.stderr.toString === 'function';
    }
    return false;
}
function launchDevice(deviceUid) {
    try {
        child_process_1.default.execSync(['xcrun', 'simctl', 'boot', deviceUid].join(' '));
    }
    catch (e) {
        if (isErrorWithStderr(e)) {
            const err = e.stderr.toString();
            if (err.includes('Unable to boot device in current state: Booted')) {
                return;
            }
        }
        throw e;
    }
}
async function promptForDeviceSelection(allDevices) {
    const { devices } = await (0, prompts_1.default)({
        type: 'multiselect',
        name: 'devices',
        message: 'Select the device / emulator you want to use',
        choices: allDevices.map(d => ({
            title: `${chalk_1.default.bold(`(${d.type})`)} ${chalk_1.default.green(`${d.name}`)} (${d.state === 'Booted' ? 'connected' : 'disconnected'})`,
            value: d,
        })),
        min: 1,
    });
    return devices;
}
async function runApp(buildType, iosPlatform = iosUtils_1.iosBuildPlatforms.simulator) {
    const buildFlavor = (0, config_1.getIosFlavors)(buildType);
    if (!checkBuildPresent(buildFlavor.scheme, iosPlatform)) {
        logger_1.default.info('Build not present, starting build');
        (0, buildIos_1.buildIos)(buildType, iosPlatform);
    }
    else {
        logger_1.default.info('Build already present, skipping build');
    }
    const devices = getDevices();
    if (devices.length === 0) {
        throw new Error('No iOS devices available');
    }
    // todo improve run on device
    (0, utils_1.executeCommand)('open -a Simulator');
    let bootedDevices = getBootedDevices(devices);
    const devicesToRun = [];
    if (bootedDevices.length === 1) {
        devicesToRun.push(bootedDevices[0]);
    }
    else {
        const requestedDevices = await promptForDeviceSelection(devices);
        for (const requestedDevice of requestedDevices) {
            if (!(requestedDevice.state === 'Booted')) {
                launchDevice(requestedDevice.udid);
            }
        }
        // start not connected ones
        devicesToRun.push(...requestedDevices);
    }
    const { destination } = (0, iosUtils_1.getIosBuildDestination)(iosPlatform, buildFlavor.scheme);
    const bundleID = (0, child_process_1.execFileSync)('/usr/libexec/PlistBuddy', ['-c', 'Print:CFBundleIdentifier', path_1.default.join(destination, 'Info.plist')], {
        encoding: 'utf8',
    }).trim();
    for (const device of devicesToRun) {
        const id = device.udid;
        installApp(id, buildFlavor.scheme, iosPlatform);
        launchApp(id, bundleID);
    }
}
exports.runApp = runApp;
