"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const enums_1 = require("./enums");
const android_controller_1 = require("./android-controller");
const ios_controller_1 = require("./ios-controller");
const utils = require("./utils");
class DeviceController {
    /**
     *
     * @param query of type IDevice
     */
    static getDevices(query) {
        return __awaiter(this, void 0, void 0, function* () {
            const searchQuery = DeviceController.copyProperties(query);
            const devices = yield DeviceController.mapDevicesToArray(searchQuery);
            return devices;
        });
    }
    static startDevice(device, options, shouldHardResetDevices = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const type = device.type || device['_type'];
            const platform = device.platform || device['_platform'];
            if (!device.type && !device.platform) {
                device = (yield DeviceController.getDevices(device))[0];
            }
            if (!device) {
                utils.logError(`Device doesn't exist!`);
            }
            if (type === enums_1.DeviceType.EMULATOR || platform === enums_1.Platform.ANDROID) {
                options = shouldHardResetDevices ? (options || "") + " -wipe-data " : options;
                const emuOptions = options ? options.split(" ").filter(o => o.trim()) : undefined;
                return yield android_controller_1.AndroidController.startEmulator(device, emuOptions);
            }
            else {
                return yield ios_controller_1.IOSController.startSimulator(device, options, shouldHardResetDevices);
            }
        });
    }
    static refreshApplication(device, appFullPath) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS) {
                yield ios_controller_1.IOSController.refreshApplication(device, appFullPath);
            }
            else {
                yield android_controller_1.AndroidController.refreshApplication(device, appFullPath);
            }
        });
    }
    static startApplication(device, appFullPath, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS) {
                yield ios_controller_1.IOSController.startApplication(device, appFullPath, bundleId);
            }
            else {
                yield android_controller_1.AndroidController.startApplication(device, bundleId);
            }
        });
    }
    static getInstalledApplication(device) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS) {
                return yield ios_controller_1.IOSController.getInstalledApps(device);
            }
            else {
                return yield android_controller_1.AndroidController.getInstalledApps(device);
            }
        });
    }
    /**
     *
     * @param device { token: string, type: DeviceType, platform: Platform }
     * @param bundleId or package id
     * @param appName required for ios devices
     */
    static stopApplication(device, bundleId, appName) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS || device.type === enums_1.DeviceType.SIMULATOR) {
                yield ios_controller_1.IOSController.stopApplication(device, bundleId, appName);
            }
            else {
                yield android_controller_1.AndroidController.stopApplication(device, bundleId);
            }
        });
    }
    static getApplicationId(device, appFullPath) {
        if (device.platform === enums_1.Platform.IOS) {
            return ios_controller_1.IOSController.getIOSPackageId(device.type, appFullPath);
        }
        else {
            return android_controller_1.AndroidController.getPackageId(appFullPath);
        }
    }
    static uninstallApp(device, appFullPath) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS) {
                const bundleId = ios_controller_1.IOSController.getIOSPackageId(device.type, appFullPath);
                yield ios_controller_1.IOSController.uninstallApp(device, appFullPath, bundleId);
            }
            else {
                const packageId = android_controller_1.AndroidController.getPackageId(appFullPath);
                yield android_controller_1.AndroidController.uninstallApp(device, packageId);
            }
        });
    }
    static startRecordingVideo(device, dir, fileName) {
        if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
            return android_controller_1.AndroidController.startRecordingVideo(device, dir, fileName);
        }
        else {
            return ios_controller_1.IOSController.startRecordingVideo(device, dir, fileName);
        }
    }
    static kill(device) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!device.type && !device.platform) {
                device = (yield DeviceController.getDevices(device))[0];
            }
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                yield android_controller_1.AndroidController.kill(device);
            }
            else {
                yield ios_controller_1.IOSController.kill(device.token);
            }
            utils.wait(2000);
        });
    }
    static killAll(type) {
        if (type === enums_1.DeviceType.EMULATOR) {
            android_controller_1.AndroidController.killAll();
        }
        else {
            ios_controller_1.IOSController.killAll();
        }
    }
    static refreshDeviceStatus(token, platform = undefined, verbose = false) {
        return __awaiter(this, void 0, void 0, function* () {
            if (token) {
                const devices = yield DeviceController.getDevices({ token: token });
                const device = devices.filter(e => e.token === token)[0];
                return device != null ? device.status : enums_1.Status.SHUTDOWN;
            }
            if (platform === enums_1.Platform.ANDROID) {
                const emulators = android_controller_1.AndroidController.parseRunningDevicesList(verbose);
                const emulator = emulators.filter(e => e.token === token)[0];
                return emulator != null ? emulator.status : enums_1.Status.SHUTDOWN;
            }
            if (platform === enums_1.Platform.IOS) {
                const simulators = yield DeviceController.mapDevicesToArray({ platform: enums_1.Platform.IOS });
                const simulator = simulators.filter(e => e.token === token)[0];
                return simulator != null ? simulator.status : enums_1.Status.SHUTDOWN;
            }
        });
    }
    static getRunningDevices(shouldFailOnError) {
        return __awaiter(this, void 0, void 0, function* () {
            const devices = new Array();
            const emulators = android_controller_1.AndroidController.parseRunningDevicesList(false);
            for (let index = 0; index < emulators.length; index++) {
                const emulator = emulators[index];
                emulator.name = yield android_controller_1.AndroidController.sendTelnetCommand(emulator.token, "avd name", shouldFailOnError);
            }
            devices.push(...emulators);
            const simulators = (yield DeviceController.mapDevicesToArray({ platform: enums_1.Platform.IOS }))
                .filter(d => d.status === enums_1.Status.BOOTED);
            devices.push(...simulators);
            return devices;
        });
    }
    static filter(devices, searchQuery) {
        return utils.filter(devices, searchQuery);
    }
    static getScreenshot(device, dir, fileName) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                return android_controller_1.AndroidController.getScreenshot(device, dir, fileName);
            }
            else {
                return ios_controller_1.IOSController.getScreenshot(device, dir, fileName);
            }
        });
    }
    static recordVideo(device, dir, fileName, callback) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                return android_controller_1.AndroidController.recordVideo(device, dir, fileName, callback);
            }
            else {
                return ios_controller_1.IOSController.recordVideo(device, dir, fileName, callback);
            }
        });
    }
    static reinstallApplication(device, appFullName, bundleId) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                return yield android_controller_1.AndroidController.reinstallApplication(device, appFullName, bundleId);
            }
            else {
                return yield ios_controller_1.IOSController.reinstallApplication(device, appFullName, bundleId);
            }
        });
    }
    static installApplication(device, appFullName, bundleId = undefined) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                return yield android_controller_1.AndroidController.installApp(device, appFullName, bundleId);
            }
            else {
                return yield ios_controller_1.IOSController.installApp(device, appFullName);
            }
        });
    }
    static uninstallAppWithBundle(device, bundleId) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.type === enums_1.DeviceType.EMULATOR || device.platform === enums_1.Platform.ANDROID) {
                return yield android_controller_1.AndroidController.uninstallApp(device, bundleId);
            }
            else {
                return yield ios_controller_1.IOSController.uninstallApp(device, undefined, bundleId);
            }
        });
    }
    static copyProperties(from) {
        let to = {};
        if (!from)
            return to;
        Object.assign(to, from);
        Object.getOwnPropertyNames(to).forEach(prop => !to[prop] && delete to[prop]);
        return to;
    }
    static mapDevicesToArray(query, verbose = false) {
        return __awaiter(this, void 0, void 0, function* () {
            const devices = new Array();
            if (utils.isMac() && !query.platform || (query.platform && query.platform.toLowerCase() === enums_1.Platform.IOS)) {
                (yield ios_controller_1.IOSController.getAllDevices(verbose))
                    .forEach((v, k, map) => v.forEach(d => utils.filterPredicate(query, d) && devices.push(d)));
            }
            if (!query.platform || (query.platform && query.platform.toLowerCase() === enums_1.Platform.ANDROID)) {
                (yield android_controller_1.AndroidController.getAllDevices(verbose))
                    .forEach((v, k, map) => v.forEach(d => utils.filterAndroidPredicate(query, d) && devices.push(d)));
            }
            return devices;
        });
    }
}
exports.DeviceController = DeviceController;
process.once('exit', () => {
    android_controller_1.AndroidController.runningProcesses.forEach(proc => {
        try {
            process.kill(proc);
        }
        catch (error) { }
    });
    ios_controller_1.IOSController.runningProcesses.forEach(proc => {
        try {
            process.kill(proc);
        }
        catch (error) { }
    });
});
//# sourceMappingURL=device-controller.js.map