"use strict";
const path = require("path");
const temp = require("temp");
class AndroidDeviceHashService {
    constructor(adb, appIdentifier, $fs, $mobileHelper) {
        this.adb = adb;
        this.appIdentifier = appIdentifier;
        this.$fs = $fs;
        this.$mobileHelper = $mobileHelper;
        this._hashFileDevicePath = null;
        this._hashFileLocalPath = null;
        this._tempDir = null;
    }
    get hashFileDevicePath() {
        if (!this._hashFileDevicePath) {
            this._hashFileDevicePath = this.$mobileHelper.buildDevicePath(AndroidDeviceHashService.DEVICE_ROOT_PATH, this.appIdentifier, AndroidDeviceHashService.HASH_FILE_NAME);
        }
        return this._hashFileDevicePath;
    }
    doesShasumFileExistsOnDevice() {
        return (() => {
            let lsResult = this.adb.executeShellCommand(["ls", this.hashFileDevicePath]).wait();
            return !!(lsResult && lsResult.trim() === this.hashFileDevicePath);
        }).future()();
    }
    getShasumsFromDevice() {
        return (() => {
            let hashFileLocalPath = this.downloadHashFileFromDevice().wait();
            if (this.$fs.exists(hashFileLocalPath).wait()) {
                return this.$fs.readJson(hashFileLocalPath).wait();
            }
            return null;
        }).future()();
    }
    uploadHashFileToDevice(data) {
        return (() => {
            let shasums = {};
            if (_.isArray(data)) {
                data.forEach(localToDevicePathData => {
                    let localPath = localToDevicePathData.getLocalPath();
                    let stats = this.$fs.getFsStats(localPath).wait();
                    if (stats.isFile()) {
                        let fileShasum = this.$fs.getFileShasum(localPath).wait();
                        shasums[localPath] = fileShasum;
                    }
                });
            }
            else {
                shasums = data;
            }
            this.$fs.writeJson(this.hashFileLocalPath, shasums).wait();
            this.adb.executeCommand(["push", this.hashFileLocalPath, this.hashFileDevicePath]).wait();
        }).future()();
    }
    updateHashes(localToDevicePaths) {
        return (() => {
            let oldShasums = this.getShasumsFromDevice().wait();
            if (oldShasums) {
                _.each(localToDevicePaths, ldp => {
                    let localPath = ldp.getLocalPath();
                    if (this.$fs.getFsStats(localPath).wait().isFile()) {
                        oldShasums[localPath] = this.$fs.getFileShasum(localPath).wait();
                    }
                });
                this.uploadHashFileToDevice(oldShasums).wait();
                return true;
            }
            return false;
        }).future()();
    }
    removeHashes(localToDevicePaths) {
        return (() => {
            let oldShasums = this.getShasumsFromDevice().wait();
            if (oldShasums) {
                let fileToShasumDictionary = (_.omit(oldShasums, localToDevicePaths.map(ldp => ldp.getLocalPath())));
                this.uploadHashFileToDevice(fileToShasumDictionary).wait();
                return true;
            }
            return false;
        }).future()();
    }
    get hashFileLocalPath() {
        if (!this._hashFileLocalPath) {
            this._hashFileLocalPath = path.join(this.tempDir, AndroidDeviceHashService.HASH_FILE_NAME);
        }
        return this._hashFileLocalPath;
    }
    get tempDir() {
        if (!this._tempDir) {
            temp.track();
            this._tempDir = temp.mkdirSync(`android-device-hash-service-${this.appIdentifier}`);
        }
        return this._tempDir;
    }
    downloadHashFileFromDevice() {
        return (() => {
            if (!this.$fs.exists(this.hashFileLocalPath).wait()) {
                this.adb.executeCommand(["pull", this.hashFileDevicePath, this.tempDir]).wait();
            }
            return this.hashFileLocalPath;
        }).future()();
    }
}
AndroidDeviceHashService.HASH_FILE_NAME = "hashes";
AndroidDeviceHashService.DEVICE_ROOT_PATH = "/data/local/tmp";
exports.AndroidDeviceHashService = AndroidDeviceHashService;
