"use strict";
const path = require("path");
const temp = require("temp");
class LiveSyncProvider {
    constructor($androidLiveSyncServiceLocator, $androidPlatformLiveSyncServiceLocator, $iosLiveSyncServiceLocator, $iosPlatformLiveSyncServiceLocator, $platformService, $platformsData, $logger, $childProcess, $options, $devicePlatformsConstants) {
        this.$androidLiveSyncServiceLocator = $androidLiveSyncServiceLocator;
        this.$androidPlatformLiveSyncServiceLocator = $androidPlatformLiveSyncServiceLocator;
        this.$iosLiveSyncServiceLocator = $iosLiveSyncServiceLocator;
        this.$iosPlatformLiveSyncServiceLocator = $iosPlatformLiveSyncServiceLocator;
        this.$platformService = $platformService;
        this.$platformsData = $platformsData;
        this.$logger = $logger;
        this.$childProcess = $childProcess;
        this.$options = $options;
        this.$devicePlatformsConstants = $devicePlatformsConstants;
        this.deviceSpecificLiveSyncServicesCache = {};
        this.platformSpecificLiveSyncServicesCache = {};
    }
    get deviceSpecificLiveSyncServices() {
        return {
            android: (_device, $injector) => {
                if (!this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
                    this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$androidLiveSyncServiceLocator.factory, { _device: _device });
                }
                return this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
            },
            ios: (_device, $injector) => {
                if (!this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
                    this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$iosLiveSyncServiceLocator.factory, { _device: _device });
                }
                return this.deviceSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
            }
        };
    }
    get platformSpecificLiveSyncServices() {
        return {
            android: (_liveSyncData, $injector) => {
                if (!this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.Android]) {
                    this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.Android] = $injector.resolve(this.$androidPlatformLiveSyncServiceLocator.factory, { _liveSyncData: _liveSyncData });
                }
                return this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.Android];
            },
            ios: (_liveSyncData, $injector) => {
                if (!this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.iOS]) {
                    this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.iOS] = $injector.resolve(this.$iosPlatformLiveSyncServiceLocator.factory, { _liveSyncData: _liveSyncData });
                }
                return this.platformSpecificLiveSyncServicesCache[this.$devicePlatformsConstants.iOS];
            }
        };
    }
    buildForDevice(device) {
        return (() => {
            this.$platformService.buildPlatform(device.deviceInfo.platform, { buildForDevice: !device.isEmulator }).wait();
            let platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform);
            if (device.isEmulator) {
                return this.$platformService.getLatestApplicationPackageForEmulator(platformData).packageName;
            }
            return this.$platformService.getLatestApplicationPackageForDevice(platformData).packageName;
        }).future()();
    }
    preparePlatformForSync(platform) {
        return (() => {
            this.$platformService.preparePlatform(platform).wait();
        }).future()();
    }
    canExecuteFastSync(filePath, platform) {
        let platformData = this.$platformsData.getPlatformData(platform);
        let fastSyncFileExtensions = LiveSyncProvider.FAST_SYNC_FILE_EXTENSIONS.concat(platformData.fastLivesyncFileExtensions);
        return _.includes(fastSyncFileExtensions, path.extname(filePath));
    }
    transferFiles(deviceAppData, localToDevicePaths, projectFilesPath, isFullSync) {
        return (() => {
            if (deviceAppData.platform.toLowerCase() === "android" || !deviceAppData.deviceSyncZipPath || !isFullSync) {
                deviceAppData.device.fileSystem.transferFiles(deviceAppData, localToDevicePaths).wait();
            }
            else {
                temp.track();
                let tempZip = temp.path({ prefix: "sync", suffix: ".zip" });
                this.$logger.trace("Creating zip file: " + tempZip);
                if (this.$options.syncAllFiles) {
                    this.$childProcess.spawnFromEvent("zip", ["-r", "-0", tempZip, "app"], "close", { cwd: path.dirname(projectFilesPath) }).wait();
                }
                else {
                    this.$childProcess.spawnFromEvent("zip", ["-r", "-0", tempZip, "app", "-x", "app/tns_modules/*"], "close", { cwd: path.dirname(projectFilesPath) }).wait();
                }
                deviceAppData.device.fileSystem.transferFiles(deviceAppData, [{
                        getLocalPath: () => tempZip,
                        getDevicePath: () => deviceAppData.deviceSyncZipPath,
                        getRelativeToProjectBasePath: () => "../sync.zip",
                        deviceProjectRootPath: deviceAppData.deviceProjectRootPath
                    }]).wait();
            }
        }).future()();
    }
}
LiveSyncProvider.FAST_SYNC_FILE_EXTENSIONS = [".css", ".xml", ".html"];
exports.LiveSyncProvider = LiveSyncProvider;
$injector.register("liveSyncProvider", LiveSyncProvider);
