"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_1 = require("./utils");
class DeviceController {
    static getDivices(query) {
        return __awaiter(this, void 0, void 0, function* () {
            return DeviceController.getDevices(query);
        });
    }
    /**
     *
     * @param query should be like IDevice
     */
    static getDevices(query) {
        return __awaiter(this, void 0, void 0, function* () {
            const searchQuery = DeviceController.copyProperties(query);
            const devices = new Array();
            if (!searchQuery || !searchQuery.platform) {
                yield DeviceController.mapDevicesToArray(enums_1.Platform.ANDROID, devices);
                yield DeviceController.mapDevicesToArray(enums_1.Platform.IOS, devices);
            }
            else if (searchQuery && searchQuery.platform && !searchQuery.name) {
                yield DeviceController.mapDevicesToArray(searchQuery.platform, devices);
                delete searchQuery.platform;
            }
            else if (searchQuery && searchQuery.platform && searchQuery.name) {
                (yield DeviceController.getDevicesByPlatformAndName(searchQuery.platform, searchQuery.name)).forEach(d => {
                    if (!devices.some(currentDevice => currentDevice.token === d.token)) {
                        devices.push(d);
                    }
                });
                delete searchQuery.platform;
                delete searchQuery.name;
            }
            const filteredDevices = DeviceController.filter(devices, searchQuery);
            return filteredDevices;
        });
    }
    static startDevice(device, options) {
        return __awaiter(this, void 0, void 0, function* () {
            const type = device.type || device['_type'];
            if (type === enums_1.DeviceType.EMULATOR) {
                return yield android_controller_1.AndroidController.startEmulator(device, options);
            }
            else {
                return yield ios_controller_1.IOSController.startSimulator(device);
            }
        });
    }
    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);
            }
        });
    }
    static stopApplication(device, bundleId) {
        return __awaiter(this, void 0, void 0, function* () {
            if (device.platform === enums_1.Platform.IOS) {
                yield ios_controller_1.IOSController.stopApplication(device, bundleId);
            }
            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 === enums_1.DeviceType.EMULATOR) {
                yield android_controller_1.AndroidController.kill(device);
            }
            else {
                yield ios_controller_1.IOSController.kill(device.token);
            }
            utils_1.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 (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(enums_1.Platform.IOS, new Array());
                const simulator = simulators.filter(e => e.token === token)[0];
                return simulator != null ? simulator.status : enums_1.Status.SHUTDOWN;
            }
            if (token) {
                const devices = yield DeviceController.getDevices({});
                const device = devices.filter(e => e.token === token)[0];
                return device != null ? device.status : enums_1.Status.SHUTDOWN;
            }
        });
    }
    static filter(devices, searchQuery) {
        return devices.filter((device) => {
            if (!searchQuery || searchQuery === null || Object.getOwnPropertyNames(searchQuery).length === 0) {
                return true;
            }
            let shouldInclude = true;
            Object.getOwnPropertyNames(searchQuery).forEach((prop) => {
                if (searchQuery[prop]) {
                    if (prop.includes("apiLevel")) {
                        const searchedPlatformVersion = parseFloat(searchQuery[prop]);
                        const availablePlatofrmVersion = parseFloat(device[prop]);
                        shouldInclude = searchedPlatformVersion === availablePlatofrmVersion && shouldInclude;
                    }
                    else {
                        shouldInclude = searchQuery[prop] === device[prop] && shouldInclude;
                    }
                }
            });
            return shouldInclude;
        });
    }
    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) {
        const to = { platform: undefined, token: undefined, name: undefined, type: undefined };
        if (!from || Object.getOwnPropertyNames(from).length <= 0) {
            return undefined;
        }
        Object.getOwnPropertyNames(from).forEach((prop) => {
            if (from[prop]) {
                to[prop] = from[prop];
            }
        });
        Object.getOwnPropertyNames(to).forEach((prop) => {
            if (!to[prop]) {
                delete to[prop];
            }
        });
        return to;
    }
    static getAllDevicesByPlatform(platform, verbose = false) {
        return __awaiter(this, void 0, void 0, function* () {
            let devices = new Map();
            if (platform.toLowerCase() === enums_1.Platform.ANDROID) {
                devices = yield android_controller_1.AndroidController.getAllDevices(verbose);
            }
            else if (utils_1.isMac() && platform.toLowerCase() === enums_1.Platform.IOS) {
                devices = yield ios_controller_1.IOSController.getAllDevices(verbose);
            }
            return devices;
        });
    }
    static getDevicesByPlatformAndName(platform, name, verbose = false) {
        return __awaiter(this, void 0, void 0, function* () {
            let devices = yield DeviceController.getAllDevicesByPlatform(platform);
            if (name && devices.has(name)) {
                return devices.get(name);
            }
            else if (!name) {
                const allDevices = new Array();
                devices.forEach((v, k, map) => {
                    v.forEach((d) => {
                        allDevices.push(d);
                    });
                });
                return allDevices;
            }
            else {
                return new Array();
            }
        });
    }
    static mapDevicesToArray(platform, devices) {
        return __awaiter(this, void 0, void 0, function* () {
            const allDevices = yield DeviceController.getAllDevicesByPlatform(platform);
            allDevices.forEach((v, k, map) => {
                v.forEach(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