"use strict";
var device_android_debug_bridge_1 = require("../../common/mobile/android/device-android-debug-bridge");
var android_device_hash_service_1 = require("../../common/mobile/android/android-device-hash-service");
var Future = require("fibers/future");
var helpers = require("../../common/helpers");
var path = require("path");
var net = require("net");
var AndroidLiveSyncService = (function () {
    function AndroidLiveSyncService(_device, $fs, $mobileHelper, $options, $injector, $projectData, $androidDebugService, $liveSyncProvider) {
        this.$fs = $fs;
        this.$mobileHelper = $mobileHelper;
        this.$options = $options;
        this.$injector = $injector;
        this.$projectData = $projectData;
        this.$androidDebugService = $androidDebugService;
        this.$liveSyncProvider = $liveSyncProvider;
        this.device = (_device);
    }
    Object.defineProperty(AndroidLiveSyncService.prototype, "debugService", {
        get: function () {
            return this.$androidDebugService;
        },
        enumerable: true,
        configurable: true
    });
    AndroidLiveSyncService.prototype.refreshApplication = function (deviceAppData, localToDevicePaths, forceExecuteFullSync) {
        var _this = this;
        var canExecuteFastSync = !forceExecuteFullSync && !_.some(localToDevicePaths, function (localToDevicePath) { return !_this.$liveSyncProvider.canExecuteFastSync(localToDevicePath.getLocalPath(), deviceAppData.platform); });
        if (canExecuteFastSync) {
            return this.reloadPage(deviceAppData, localToDevicePaths);
        }
        return this.restartApplication(deviceAppData);
    };
    AndroidLiveSyncService.prototype.restartApplication = function (deviceAppData) {
        var _this = this;
        return (function () {
            _this.device.adb.executeShellCommand(["chmod", "777", deviceAppData.deviceProjectRootPath, ("/data/local/tmp/" + deviceAppData.appIdentifier)]).wait();
            var devicePathRoot = "/data/data/" + deviceAppData.appIdentifier + "/files";
            var devicePath = _this.$mobileHelper.buildDevicePath(devicePathRoot, "code_cache", "secondary_dexes", "proxyThumb");
            _this.device.adb.executeShellCommand(["rm", "-rf", devicePath]).wait();
            _this.device.applicationManager.restartApplication(deviceAppData.appIdentifier).wait();
        }).future()();
    };
    AndroidLiveSyncService.prototype.beforeLiveSyncAction = function (deviceAppData) {
        var _this = this;
        return (function () {
            var deviceRootPath = _this.getDeviceRootPath(deviceAppData.appIdentifier), deviceRootDir = path.dirname(deviceRootPath), deviceRootBasename = path.basename(deviceRootPath), listResult = _this.device.adb.executeShellCommand(["ls", "-l", deviceRootDir]).wait(), regex = new RegExp("^-.*" + deviceRootBasename + "$", "m"), matchingFile = (listResult || "").match(regex);
            if (matchingFile && matchingFile[0] && _.startsWith(matchingFile[0], '-')) {
                _this.device.adb.executeShellCommand(["rm", "-f", deviceRootPath]).wait();
            }
            _this.device.adb.executeShellCommand(["rm", "-rf", _this.$mobileHelper.buildDevicePath(deviceRootPath, "fullsync"),
                _this.$mobileHelper.buildDevicePath(deviceRootPath, "sync"),
                _this.$mobileHelper.buildDevicePath(deviceRootPath, "removedsync")]).wait();
        }).future()();
    };
    AndroidLiveSyncService.prototype.reloadPage = function (deviceAppData, localToDevicePaths) {
        var _this = this;
        return (function () {
            _this.device.adb.executeCommand(["forward", ("tcp:" + AndroidLiveSyncService.BACKEND_PORT.toString()), ("localabstract:" + deviceAppData.appIdentifier + "-livesync")]).wait();
            _this.sendPageReloadMessage().wait();
        }).future()();
    };
    AndroidLiveSyncService.prototype.removeFiles = function (appIdentifier, localToDevicePaths) {
        var _this = this;
        return (function () {
            var deviceRootPath = _this.getDeviceRootPath(appIdentifier);
            _.each(localToDevicePaths, function (localToDevicePathData) {
                var relativeUnixPath = _.trimStart(helpers.fromWindowsRelativePathToUnix(localToDevicePathData.getRelativeToProjectBasePath()), "/");
                var deviceFilePath = _this.$mobileHelper.buildDevicePath(deviceRootPath, "removedsync", relativeUnixPath);
                _this.device.adb.executeShellCommand(["mkdir", "-p", path.dirname(deviceFilePath), "&&", "touch", deviceFilePath]).wait();
            });
            _this.deviceHashService.removeHashes(localToDevicePaths).wait();
        }).future()();
    };
    AndroidLiveSyncService.prototype.afterInstallApplicationAction = function (deviceAppData, localToDevicePaths) {
        var _this = this;
        return (function () {
            _this.deviceHashService.uploadHashFileToDevice(localToDevicePaths).wait();
            return false;
        }).future()();
    };
    AndroidLiveSyncService.prototype.getDeviceRootPath = function (appIdentifier) {
        return "/data/local/tmp/" + appIdentifier;
    };
    AndroidLiveSyncService.prototype.sendPageReloadMessage = function () {
        var future = new Future();
        var socket = new net.Socket();
        socket.connect(AndroidLiveSyncService.BACKEND_PORT, '127.0.0.1', function () {
            socket.write(new Buffer([0, 0, 0, 1, 1]));
        });
        socket.on("data", function (data) {
            socket.destroy();
            future.return();
        });
        return future;
    };
    Object.defineProperty(AndroidLiveSyncService.prototype, "deviceHashService", {
        get: function () {
            if (!this._deviceHashService) {
                var adb = this.$injector.resolve(device_android_debug_bridge_1.DeviceAndroidDebugBridge, { identifier: this.device.deviceInfo.identifier });
                this._deviceHashService = this.$injector.resolve(android_device_hash_service_1.AndroidDeviceHashService, { adb: adb, appIdentifier: this.$projectData.projectId });
            }
            return this._deviceHashService;
        },
        enumerable: true,
        configurable: true
    });
    AndroidLiveSyncService.BACKEND_PORT = 18182;
    return AndroidLiveSyncService;
}());
$injector.register("androidLiveSyncServiceLocator", { factory: AndroidLiveSyncService });
