"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AndroidDeviceDiscovery = void 0;
const device_discovery_1 = require("./device-discovery");
const android_device_1 = require("../android/android-device");
const yok_1 = require("../../yok");
const _ = require("lodash");
class AndroidDeviceDiscovery extends device_discovery_1.DeviceDiscovery {
    constructor($injector, $adb, $mobileHelper) {
        super();
        this.$injector = $injector;
        this.$adb = $adb;
        this.$mobileHelper = $mobileHelper;
        this._devices = [];
    }
    async createAndAddDevice(adbDeviceInfo) {
        this._devices.push(adbDeviceInfo);
        const device = this.$injector.resolve(android_device_1.AndroidDevice, { identifier: adbDeviceInfo.identifier, status: adbDeviceInfo.status });
        await device.init();
        this.addDevice(device);
    }
    deleteAndRemoveDevice(deviceIdentifier) {
        _.remove(this._devices, (d) => d.identifier === deviceIdentifier);
        this.removeDevice(deviceIdentifier);
    }
    async startLookingForDevices(options) {
        if (options &&
            options.platform &&
            !this.$mobileHelper.isAndroidPlatform(options.platform)) {
            return;
        }
        await this.ensureAdbServerStarted();
        await this.checkForDevices();
    }
    async checkForDevices() {
        const devices = await this.$adb.getDevices();
        await this.checkCurrentData(devices);
    }
    async checkCurrentData(result) {
        const currentDevices = result.map((element) => {
            const data = element.split("\t");
            const identifier = data[0];
            const status = data[1];
            return {
                identifier: identifier,
                status: status,
            };
        });
        _(this._devices)
            .reject((d) => (_.find(currentDevices, (device) => device.identifier === d.identifier && device.status === d.status)))
            .each((d) => this.deleteAndRemoveDevice(d.identifier));
        await Promise.all(_(currentDevices)
            .reject((d) => (_.find(this._devices, (device) => device.identifier === d.identifier &&
            device.status === d.status)))
            .map((d) => this.createAndAddDevice(d))
            .value());
    }
    async ensureAdbServerStarted() {
        if (!this.isStarted) {
            this.isStarted = true;
            try {
                return await this.$adb.executeCommand(["start-server"]);
            }
            catch (err) {
                this.isStarted = false;
                throw err;
            }
        }
    }
}
exports.AndroidDeviceDiscovery = AndroidDeviceDiscovery;
yok_1.injector.register("androidDeviceDiscovery", AndroidDeviceDiscovery);
