"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 virtual_device_1 = require("../mobile-base/virtual-device");
const DeviceSignals_1 = require("../enums/DeviceSignals");
const ios_controller_1 = require("../ios-controller");
const child_process_1 = require("child_process");
const utils_1 = require("../utils");
class IOSVirtualDevice extends virtual_device_1.VirtualDevice {
    constructor() {
        super();
        this._invisibleAppsCounter = 0;
        this._shouldTestForErrors = false;
    }
    startDevice(device) {
        const _super = Object.create(null, {
            subscribeForEvents: { get: () => super.subscribeForEvents }
        });
        return __awaiter(this, void 0, void 0, function* () {
            this._device = (yield ios_controller_1.IOSController.startSimulator(device));
            this._deviceProcess = child_process_1.spawn("xcrun", ["simctl", "spawn", this._device.token, "log", "stream", "--level=info"], {
                shell: true,
                detached: true,
                stdio: ['pipe']
            });
            _super.subscribeForEvents.call(this);
            this.emit(DeviceSignals_1.DeviceSignal.onDeviceStartedSignal, this._device);
            setTimeout(() => {
                this._shouldTestForErrors = true;
                this._invisibleAppsCounter = 0;
                console.log("Watching for errors!");
            }, 120000);
            return this._device;
        });
    }
    attachToDevice(device) {
        return __awaiter(this, void 0, void 0, function* () {
            this._deviceProcess = child_process_1.spawn("xcrun", ["simctl", "spawn", this._device.token, "log", "stream", "--level=info"], {
                shell: true,
                detached: true,
                stdio: ['pipe']
            });
            this.emit(DeviceSignals_1.DeviceSignal.onDeviceAttachedSignal, device);
            this._device = device || this._device;
            return device;
        });
    }
    stopDevice() {
        ios_controller_1.IOSController.kill(this._device.token);
        if (this._deviceProcess) {
            this.emit(DeviceSignals_1.DeviceSignal.onDeviceKilledSignal, this._device);
            this._deviceProcess.kill("SIGTERM");
            this._deviceProcess.removeAllListeners();
            this._deviceProcess = null;
        }
    }
    onDeviceStarted() {
        utils_1.logInfo(`Device has started successfully!!!`, this._device);
    }
    onDeviceError(...args) {
        utils_1.logError(`An error ocurred!!!`, this._device);
    }
    onDeviceKilled(args) {
        utils_1.logWarn("Killed: ", args);
    }
    onAttachToDevice(deviceInfo) {
        this._device = deviceInfo;
    }
    stdout(...args) {
        return __awaiter(this, void 0, void 0, function* () {
            if (args.toString().includes("Skipping invisible app")) {
                this._invisibleAppsCounter++;
            }
            // if (this._invisibleAppsCounter > 10 && this._shouldTestForErrors) {
            //     logError("Detecting too many invisible applications in simulator log. Probably simulator has a black screen and doesn't respond!");
            //     await IOSController.kill(this.device.token);
            //     await this.startDevice(this._device);
            // }
        });
    }
    stdin(args) {
        console.log("stdin: ", args.toString());
    }
}
exports.IOSVirtualDevice = IOSVirtualDevice;
//# sourceMappingURL=ios-virtual-device.js.map