"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 child_process_1 = require("child_process");
const virtual_device_1 = require("../mobile-base/virtual-device");
const DeviceSignals_1 = require("../enums/DeviceSignals");
const ios_controller_1 = require("../ios-controller");
const utils_1 = require("../utils");
class IOSVirtualDevice extends virtual_device_1.VirtualDevice {
    constructor() { super(); }
    startDevice(device) {
        const _super = Object.create(null, {
            subscribeForEvents: { get: () => super.subscribeForEvents }
        });
        return __awaiter(this, void 0, void 0, function* () {
            this.detachFromEventListeners();
            this._device = (yield ios_controller_1.IOSController.startSimulator(device));
            this._deviceProcess = IOSVirtualDevice.spawnLog(this._device.token);
            _super.subscribeForEvents.call(this);
            this._isAlive = true;
            this.emit(DeviceSignals_1.DeviceSignal.onDeviceAttachedSignal, this._device);
            return this._device;
        });
    }
    attachToDevice(device) {
        const _super = Object.create(null, {
            subscribeForEvents: { get: () => super.subscribeForEvents }
        });
        return __awaiter(this, void 0, void 0, function* () {
            if (this._isAttached)
                return;
            this._isAttached = true;
            this._isAlive = true;
            this._device = device || this._device;
            this.detachFromEventListeners();
            this._deviceProcess = IOSVirtualDevice.spawnLog(this._device.token);
            _super.subscribeForEvents.call(this);
            this.emit(DeviceSignals_1.DeviceSignal.onDeviceAttachedSignal, this._device);
        });
    }
    detach() {
        this._isAttached = false;
        this.detachFromEventListeners();
    }
    stopDevice() {
        if (!this._isAlive)
            return;
        ios_controller_1.IOSController.kill(this._device.token);
        this._isAlive = false;
        this._isAttached = false;
        this.detachFromEventListeners();
        this.emit(DeviceSignals_1.DeviceSignal.onDeviceKilledSignal, this._device);
    }
    onDeviceStarted(deviceInfo) {
        utils_1.logInfo(`On device started!!!`, deviceInfo);
    }
    onDeviceError(args) {
        utils_1.logError(`An error ocurred!!!`, args);
    }
    onDeviceKilled(deviceInfo) {
        this.detachFromEventListeners();
        if (this._isAlive) {
            this._isAlive = false;
            utils_1.logWarn("Killed: ", deviceInfo);
        }
    }
    onDeviceAttach(deviceInfo) {
        console.log("Attached to device", deviceInfo);
    }
    detachFromEventListeners() {
        if (this._deviceProcess) {
            this._deviceProcess.kill("SIGTERM");
            this._deviceProcess.removeAllListeners();
            this._deviceProcess = null;
        }
        if (this._checkSimulatorState) {
            clearTimeout(this._checkSimulatorState);
            this._checkSimulatorState = null;
        }
    }
    static spawnLog(token) {
        return child_process_1.spawn("xcrun", ["simctl", "spawn", token, "log", "stream", "--level=info"], {
            shell: true,
            detached: false,
            stdio: 'ignore'
        });
    }
}
exports.IOSVirtualDevice = IOSVirtualDevice;
//# sourceMappingURL=ios-virtual-device.js.map