"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 __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var decorators_1 = require("../../../decorators");
var ProtonLiveSyncService = (function () {
    function ProtonLiveSyncService($devicesService, $errors, $mobileHelper, $options, $fs, $injector, $project, $logger) {
        this.$devicesService = $devicesService;
        this.$errors = $errors;
        this.$mobileHelper = $mobileHelper;
        this.$options = $options;
        this.$fs = $fs;
        this.$injector = $injector;
        this.$project = $project;
        this.$logger = $logger;
        this.excludedProjectDirsAndFiles = ["app_resources", "plugins", ".*.tmp", ".ab"];
    }
    Object.defineProperty(ProtonLiveSyncService.prototype, "$liveSyncServiceBase", {
        get: function () {
            return this.$injector.resolve("liveSyncServiceBase");
        },
        enumerable: true,
        configurable: true
    });
    ProtonLiveSyncService.prototype.livesync = function (deviceIdentifiers, projectDir, filePaths) {
        var _this = this;
        return (function () {
            _this.$project.projectDir = projectDir;
            var deviceInfos = _.map(deviceIdentifiers, function (d) {
                var matchingDevice = _.find(_this.$devicesService.getDeviceInstances(), function (device) { return device.deviceInfo.identifier === d.deviceIdentifier; });
                return _.extend(d, { device: matchingDevice });
            });
            var errors = [];
            var groupedByPlatform = _.groupBy(deviceInfos, function (d) { return d.device.deviceInfo.platform.toLowerCase(); });
            _.each(groupedByPlatform, function (platformGroup, platform) {
                var syncToApp = platformGroup.filter(function (plGr) { return !!plGr.syncToApp; });
                try {
                    _this.liveSyncToApp(platform, syncToApp.map(function (s) { return s.device; }), filePaths).wait();
                }
                catch (err) {
                    _this.$logger.trace("Error while trying to livesync applications to devices: " + syncToApp.join(", ") + ".", err.message);
                    errors.push(err);
                }
                var syncToCompanion = platformGroup.filter(function (plGr) { return !!plGr.syncToCompanion; });
                try {
                    _this.liveSyncToCompanion(platform, syncToCompanion.map(function (s) { return s.device; }), filePaths).wait();
                }
                catch (err) {
                    _this.$logger.trace("Error while trying to livesync to companion app to devices: " + syncToCompanion.join(", ") + ".", err.message);
                    errors.push(err);
                }
            });
            if (errors && errors.length) {
                throw new Error("Unable to livesync to specified devices. Errors are: " + errors.map(function (err) { return err.message; }));
            }
        }).future()();
    };
    ProtonLiveSyncService.prototype.liveSyncToApp = function (platform, devices, filePaths) {
        var _this = this;
        return (function () {
            _this.$options.companion = false;
            if (!_this.$project.capabilities.livesync) {
                _this.$errors.failWithoutHelp("You cannot use LiveSync for " + _this.$project.projectData.Framework + " projects.");
            }
            _this.liveSyncCore(platform, devices, filePaths).wait();
        }).future()();
    };
    ProtonLiveSyncService.prototype.liveSyncToCompanion = function (platform, devices, filePaths) {
        var _this = this;
        return (function () {
            _this.$options.companion = true;
            if (!_this.$mobileHelper.getPlatformCapabilities(platform).companion) {
                _this.$errors.failWithoutHelp("The Companion app is not available on " + platform + " devices.");
            }
            if (!_this.$project.capabilities.livesyncCompanion) {
                _this.$errors.failWithoutHelp("You cannot use LiveSync to Companion app for " + _this.$project.projectData.Framework + " projects.");
            }
            _this.liveSyncCore(platform, devices, filePaths).wait();
        }).future()();
    };
    ProtonLiveSyncService.prototype.liveSyncCore = function (platform, devices, filePaths) {
        var _this = this;
        return (function () {
            var livesyncData = {
                platform: platform,
                appIdentifier: _this.$project.projectData.AppIdentifier,
                projectFilesPath: _this.$project.projectDir,
                syncWorkingDirectory: _this.$project.projectDir,
                excludedProjectDirsAndFiles: _this.excludedProjectDirsAndFiles,
                canExecuteFastSync: false,
                canExecute: function (device) { return device.deviceInfo.platform.toLowerCase() === platform.toLowerCase() && !!_.any(devices, function (d) { return d.deviceInfo.identifier === device.deviceInfo.identifier; }); }
            };
            _this.$liveSyncServiceBase.sync(livesyncData, filePaths).wait();
        }).future()();
    };
    __decorate([
        decorators_1.exportedPromise("liveSyncService"), 
        __metadata('design:type', Function), 
        __metadata('design:paramtypes', [Array, String, Array]), 
        __metadata('design:returntype', Object)
    ], ProtonLiveSyncService.prototype, "livesync", null);
    return ProtonLiveSyncService;
})();
exports.ProtonLiveSyncService = ProtonLiveSyncService;
$injector.register("liveSyncService", ProtonLiveSyncService);
