"use strict";
const _ = require("lodash");
function getSimulator() {
    let libraryPath = require("./iphone-simulator");
    let obj = new libraryPath.iPhoneSimulator();
    return obj.createSimulator();
}
const publicApi = {};
Object.defineProperty(publicApi, "getRunningSimulator", {
    get: () => {
        return (...args) => {
            let isResolved = false;
            return new Promise((resolve, reject) => {
                let libraryPath = require("./iphone-simulator-xcode-simctl");
                let simulator = new libraryPath.XCodeSimctlSimulator();
                const tryGetBootedDevice = () => {
                    try {
                        return simulator.getBootedDevice.apply(simulator, args);
                    }
                    catch (err) {
                        if (!isResolved) {
                            isResolved = true;
                            reject(err);
                        }
                    }
                };
                let result = tryGetBootedDevice();
                if (!isResolved && !result) {
                    let repeatCount = 30;
                    let timer = setInterval(() => {
                        result = tryGetBootedDevice();
                        if ((result || !repeatCount) && !isResolved) {
                            isResolved = true;
                            clearInterval(timer);
                            resolve(result);
                        }
                        repeatCount--;
                    }, 500);
                }
            });
        };
    }
});
Object.defineProperty(publicApi, "getRunningSimulators", {
    get: () => {
        return (...args) => {
            let isResolved = false;
            return new Promise((resolve, reject) => {
                const libraryPath = require("./iphone-simulator-xcode-simctl");
                const simulator = new libraryPath.XCodeSimctlSimulator();
                const tryGetBootedDevices = () => {
                    try {
                        return simulator.getBootedDevices.apply(simulator, args);
                    }
                    catch (err) {
                        if (!isResolved) {
                            isResolved = true;
                            reject(err);
                        }
                    }
                };
                let result = tryGetBootedDevices();
                if (result && result.length) {
                    isResolved = true;
                    resolve(result);
                    return;
                }
                if (!isResolved && (!result || !result.length)) {
                    const timer = setTimeout(() => {
                        result = tryGetBootedDevices();
                        if (!isResolved) {
                            isResolved = true;
                            resolve(result);
                        }
                    }, 500);
                }
            });
        };
    }
});
Object.defineProperty(publicApi, "getApplicationPath", {
    get: () => {
        return (...args) => {
            let simulator = getSimulator();
            let result = simulator.getApplicationPath.apply(simulator, args);
            return result;
        };
    }
});
Object.defineProperty(publicApi, "getInstalledApplications", {
    get: () => {
        return (...args) => {
            let simulator = getSimulator();
            let installedApplications = simulator.getInstalledApplications.apply(simulator, args);
            let result = _.map(installedApplications, application => application.appIdentifier);
            return result;
        };
    }
});
Object.defineProperty(publicApi, "launchApplication", {
    get: () => {
        return (...args) => {
            const libraryPath = require("./iphone-simulator");
            const obj = new libraryPath.iPhoneSimulator();
            return obj.run.apply(obj, args);
        };
    }
});
Object.defineProperty(publicApi, "printDeviceTypes", {
    get: () => {
        return (...args) => {
            const libraryPath = require("./iphone-simulator");
            const obj = new libraryPath.iPhoneSimulator();
            return obj.printDeviceTypes.apply(obj, args);
        };
    }
});
["installApplication",
    "uninstallApplication",
    "startApplication",
    "stopApplication",
    "run",
    "getDeviceLogProcess",
    "startSimulator",
    "getSimulatorName",
    "getDevices",
    "sendNotification"].forEach(methodName => {
    Object.defineProperty(publicApi, methodName, {
        get: () => {
            return (...args) => {
                let simulator = getSimulator();
                return simulator[methodName].apply(simulator, args);
            };
        }
    });
});
module.exports = publicApi;
