"use strict";
var ios_simulator_discovery_1 = require("../../../mobile/mobile-core/ios-simulator-discovery");
var yok_1 = require("../../../yok");
var Future = require("fibers/future");
var chai_1 = require("chai");
var device_platforms_constants_1 = require("../../../mobile/device-platforms-constants");
var currentlyRunningSimulator, isCurrentlyRunning;
function createTestInjector() {
    var injector = new yok_1.Yok();
    injector.register("childProcess", {
        exec: function (command) { return Future.fromResult(isCurrentlyRunning ? 'launchd_sim' : ''); }
    });
    injector.register("injector", injector);
    injector.register("iOSSimResolver", {
        iOSSim: {
            getRunningSimulator: function () { return currentlyRunningSimulator; }
        }
    });
    injector.register("hostInfo", {
        isDarwin: true
    });
    injector.register("devicePlatformsConstants", device_platforms_constants_1.DevicePlatformsConstants);
    injector.register("iOSSimulatorDiscovery", ios_simulator_discovery_1.IOSSimulatorDiscovery);
    injector.register("iOSSimulatorLogProvider", {});
    return injector;
}
describe("ios-simulator-discovery", function () {
    var testInjector, iOSSimulatorDiscovery, defaultRunningSimulator, expectedDeviceInfo = null;
    var detectNewSimulatorAttached = function (runningSimulator) {
        var future = new Future();
        isCurrentlyRunning = true;
        currentlyRunningSimulator = _.cloneDeep(runningSimulator);
        iOSSimulatorDiscovery.once("deviceFound", function (device) {
            future.return(device);
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
        return future.wait();
    };
    var detectSimulatorDetached = function () {
        isCurrentlyRunning = false;
        currentlyRunningSimulator = null;
        var lostDeviceFuture = new Future();
        iOSSimulatorDiscovery.once("deviceLost", function (device) {
            lostDeviceFuture.return(device);
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
        return lostDeviceFuture.wait();
    };
    var detectSimulatorChanged = function (newId) {
        currentlyRunningSimulator.id = newId;
        var lostDeviceFuture = new Future(), foundDeviceFuture = new Future();
        iOSSimulatorDiscovery.on("deviceLost", function (device) {
            lostDeviceFuture.return(device);
        });
        iOSSimulatorDiscovery.on("deviceFound", function (device) {
            foundDeviceFuture.return(device);
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
        var deviceLost = lostDeviceFuture.wait();
        var deviceFound = foundDeviceFuture.wait();
        return { deviceLost: deviceLost, deviceFound: deviceFound };
    };
    beforeEach(function () {
        isCurrentlyRunning = false;
        currentlyRunningSimulator = null;
        testInjector = createTestInjector();
        iOSSimulatorDiscovery = testInjector.resolve("iOSSimulatorDiscovery");
        expectedDeviceInfo = {
            identifier: "id",
            displayName: 'name',
            model: 'c',
            version: '9.2.1',
            vendor: 'Apple',
            platform: 'iOS',
            status: 'Connected',
            errorHelp: null,
            isTablet: false,
            type: 'Emulator'
        };
        defaultRunningSimulator = {
            id: "id",
            name: "name",
            fullId: "a.b.c",
            runtimeVersion: "9.2.1",
        };
    });
    it("finds new device when it is attached", function () {
        var device = detectNewSimulatorAttached(defaultRunningSimulator);
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
    });
    it("raises deviceLost when device is detached", function () {
        var device = detectNewSimulatorAttached(defaultRunningSimulator);
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
        var lostDevice = detectSimulatorDetached();
        chai_1.assert.deepEqual(lostDevice, device);
    });
    it("raises deviceLost and deviceFound when device's id has changed (change simulator type)", function () {
        var device = detectNewSimulatorAttached(defaultRunningSimulator), newId = "newId";
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
        var devices = detectSimulatorChanged(newId);
        chai_1.assert.deepEqual(devices.deviceLost, device);
        expectedDeviceInfo.identifier = newId;
        chai_1.assert.deepEqual(devices.deviceFound.deviceInfo, expectedDeviceInfo);
    });
    it("raises events in correct order when simulator is started, closed and started again", function () {
        var device = detectNewSimulatorAttached(defaultRunningSimulator);
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
        var lostDevice = detectSimulatorDetached();
        chai_1.assert.deepEqual(lostDevice, device);
        device = detectNewSimulatorAttached(defaultRunningSimulator);
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
    });
    it("finds new device when it is attached and reports it as new only once", function () {
        var device = detectNewSimulatorAttached(defaultRunningSimulator);
        chai_1.assert.deepEqual(device.deviceInfo, expectedDeviceInfo);
        iOSSimulatorDiscovery.on("deviceFound", function (d) {
            throw new Error("Device found should not be raised for the same device.");
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
        iOSSimulatorDiscovery.startLookingForDevices().wait();
    });
    it("does not detect devices and does not throw when getting running iOS Simulator throws", function () {
        testInjector.resolve("childProcess").exec = function (command) {
            return (function () {
                throw new Error("Cannot find iOS Devices.");
            }).future()();
        };
        isCurrentlyRunning = true;
        iOSSimulatorDiscovery.on("deviceFound", function (device) {
            throw new Error("Device found should not be raised when getting running iOS Simulator fails.");
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
    });
    it("does not detect iOS Simulator when not running on OS X", function () {
        testInjector.resolve("hostInfo").isDarwin = false;
        isCurrentlyRunning = true;
        iOSSimulatorDiscovery.on("deviceFound", function (device) {
            throw new Error("Device found should not be raised when OS is not OS X.");
        });
        iOSSimulatorDiscovery.startLookingForDevices().wait();
    });
    it("checkForDevices return future", function () {
        testInjector.resolve("hostInfo").isDarwin = false;
        isCurrentlyRunning = true;
        iOSSimulatorDiscovery.on("deviceFound", function (device) {
            throw new Error("Device found should not be raised when OS is not OS X.");
        });
        iOSSimulatorDiscovery.checkForDevices().wait();
    });
});
