"use strict";
var androidDebugBridgePath = require("./android-debug-bridge");
var applicationManagerPath = require("./android-application-manager");
var fileSystemPath = require("./android-device-file-system");
var constants = require("../constants");
var AndroidDevice = (function () {
    function AndroidDevice(identifier, status, $androidEmulatorServices, $logger, $fs, $childProcess, $errors, $staticConfig, $devicePlatformsConstants, $options, $logcatHelper, $hostInfo, $mobileHelper, $injector) {
        this.identifier = identifier;
        this.status = status;
        this.$androidEmulatorServices = $androidEmulatorServices;
        this.$logger = $logger;
        this.$fs = $fs;
        this.$childProcess = $childProcess;
        this.$errors = $errors;
        this.$staticConfig = $staticConfig;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.$options = $options;
        this.$logcatHelper = $logcatHelper;
        this.$hostInfo = $hostInfo;
        this.$mobileHelper = $mobileHelper;
        this.$injector = $injector;
        this.adb = this.$injector.resolve(androidDebugBridgePath.AndroidDebugBridge, { identifier: this.identifier });
        this.applicationManager = this.$injector.resolve(applicationManagerPath.AndroidApplicationManager, { adb: this.adb, identifier: this.identifier });
        this.fileSystem = this.$injector.resolve(fileSystemPath.AndroidDeviceFileSystem, { adb: this.adb, identifier: this.identifier });
        var details;
        try {
            details = this.getDeviceDetails(["getprop"]).wait();
        }
        catch (err) {
            this.$logger.trace("Error while calling getprop: " + err.message);
        }
        if (!details || !details.name) {
            details = this.getDeviceDetails(["cat", "/system/build.prop"]).wait();
        }
        this.$logger.trace(details);
        var adbStatusInfo = AndroidDevice.ADB_DEVICE_STATUS_INFO[status];
        this.deviceInfo = {
            identifier: this.identifier,
            displayName: details.name,
            model: details.model,
            version: details.release,
            vendor: details.brand,
            platform: this.$devicePlatformsConstants.Android,
            status: adbStatusInfo ? adbStatusInfo.deviceStatus : status,
            errorHelp: adbStatusInfo ? adbStatusInfo.errorHelp : "Unknown status",
            isTablet: this.getIsTablet(details),
            type: this.getType().wait()
        };
        this.$logger.trace(this.deviceInfo);
    }
    Object.defineProperty(AndroidDevice.prototype, "isEmulator", {
        get: function () {
            return this.deviceInfo.type === "Emulator";
        },
        enumerable: true,
        configurable: true
    });
    AndroidDevice.prototype.openDeviceLogStream = function () {
        if (this.deviceInfo.status === constants.CONNECTED_STATUS) {
            this.$logcatHelper.start(this.identifier);
        }
    };
    AndroidDevice.prototype.getDeviceDetails = function (shellCommandArgs) {
        var _this = this;
        return (function () {
            var details = _this.adb.executeShellCommand(shellCommandArgs).wait();
            var parsedDetails = {};
            details.split(/\r?\n|\r/).forEach(function (value) {
                var match = /(?:\[?ro\.build\.version|ro\.product|ro\.build)\.(.+?)]?(?:\:|=)(?:\s*?\[)?(.*?)]?$/.exec(value);
                if (match) {
                    parsedDetails[match[1]] = match[2];
                }
            });
            _this.$logger.trace(parsedDetails);
            return parsedDetails;
        }).future()();
    };
    AndroidDevice.prototype.getIsTablet = function (details) {
        return details && (_.startsWith(details.release, "3.") || _.contains((details.characteristics || '').toLowerCase(), "tablet"));
    };
    AndroidDevice.prototype.getType = function () {
        var _this = this;
        return (function () {
            var runningEmulators = _this.$androidEmulatorServices.getAllRunningEmulators().wait();
            if (_.contains(runningEmulators, _this.identifier)) {
                return "Emulator";
            }
            return "Device";
        }).future()();
    };
    AndroidDevice.ADB_DEVICE_STATUS_INFO = {
        "device": {
            errorHelp: null,
            deviceStatus: constants.CONNECTED_STATUS
        },
        "offline": {
            errorHelp: "The device instance is not connected to adb or is not responding.",
            deviceStatus: constants.UNREACHABLE_STATUS
        },
        "unauthorized": {
            errorHelp: "Allow USB Debugging on your device.",
            deviceStatus: constants.UNREACHABLE_STATUS
        },
        "recovery": {
            errorHelp: "Your device is in recovery mode. This mode is used to recover your phone when it is broken or to install custom roms.",
            deviceStatus: constants.UNREACHABLE_STATUS
        },
        "no permissions": {
            errorHelp: "Insufficient permissions to communicate with the device.",
            deviceStatus: constants.UNREACHABLE_STATUS
        },
    };
    return AndroidDevice;
})();
exports.AndroidDevice = AndroidDevice;
