"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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 applicationManagerPath = require("./ios-simulator-application-manager");
const fileSystemPath = require("./ios-simulator-file-system");
const constants = require("../../../constants");
const decorators_1 = require("../../../decorators");
const helpers = require("../../../../common/helpers");
const ios_device_base_1 = require("../ios-device-base");
class IOSSimulator extends ios_device_base_1.IOSDeviceBase {
    constructor(simulator, $devicePlatformsConstants, $errors, $lockService, $injector, $iOSDebuggerPortService, $iOSSimResolver, $iOSEmulatorServices, $iOSNotification, $iOSSimulatorLogProvider, $logger, $processService) {
        super();
        this.simulator = simulator;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.$errors = $errors;
        this.$lockService = $lockService;
        this.$injector = $injector;
        this.$iOSDebuggerPortService = $iOSDebuggerPortService;
        this.$iOSSimResolver = $iOSSimResolver;
        this.$iOSEmulatorServices = $iOSEmulatorServices;
        this.$iOSNotification = $iOSNotification;
        this.$iOSSimulatorLogProvider = $iOSSimulatorLogProvider;
        this.$logger = $logger;
        this.$processService = $processService;
        this.applicationManager = this.$injector.resolve(applicationManagerPath.IOSSimulatorApplicationManager, { iosSim: this.$iOSSimResolver.iOSSim, device: this });
        this.fileSystem = this.$injector.resolve(fileSystemPath.IOSSimulatorFileSystem, { iosSim: this.$iOSSimResolver.iOSSim });
        this.deviceInfo = {
            imageIdentifier: this.simulator.id,
            identifier: this.simulator.id,
            displayName: this.simulator.name,
            model: _.last(this.simulator.fullId.split(".")),
            version: this.simulator.runtimeVersion,
            vendor: "Apple",
            platform: this.$devicePlatformsConstants.iOS,
            status: constants.CONNECTED_STATUS,
            errorHelp: null,
            isTablet: this.simulator.fullId.toLowerCase().indexOf("ipad") !== -1,
            type: constants.DeviceTypes.Emulator
        };
    }
    get isEmulator() {
        return true;
    }
    openDeviceLogStream(options) {
        return __awaiter(this, void 0, void 0, function* () {
            options = options || {};
            options.predicate = options.hasOwnProperty("predicate") ? options.predicate : constants.IOS_LOG_PREDICATE;
            return this.$iOSSimulatorLogProvider.startLogProcess(this.simulator.id, options);
        });
    }
    getSocketCore(appId) {
        return __awaiter(this, void 0, void 0, function* () {
            let socket;
            const attachRequestMessage = this.$iOSNotification.getAttachRequest(appId, this.deviceInfo.identifier);
            yield this.$iOSEmulatorServices.postDarwinNotification(attachRequestMessage, this.deviceInfo.identifier);
            const port = yield this.getDebuggerPort(appId);
            try {
                socket = yield helpers.connectEventuallyUntilTimeout(() => __awaiter(this, void 0, void 0, function* () { return this.$iOSEmulatorServices.connectToPort({ port }); }), constants.SOCKET_CONNECTION_TIMEOUT_MS);
            }
            catch (e) {
                this.$logger.warn(e);
            }
            return socket;
        });
    }
}
__decorate([
    decorators_1.cache()
], IOSSimulator.prototype, "openDeviceLogStream", null);
exports.IOSSimulator = IOSSimulator;
