"use strict";
let gaze = require("gaze");
const path = require("path");
const os = require("os");
const Future = require("fibers/future");
let hostInfo = $injector.resolve("hostInfo");
class CancellationService {
    constructor($fs, $logger) {
        this.$fs = $fs;
        this.$logger = $logger;
        this.watches = {};
        this.$fs.createDirectory(CancellationService.killSwitchDir);
        this.$fs.chmod(CancellationService.killSwitchDir, "0777");
    }
    begin(name) {
        return (() => {
            let triggerFile = CancellationService.makeKillSwitchFileName(name);
            if (!this.$fs.exists(triggerFile)) {
                let stream = this.$fs.createWriteStream(triggerFile);
                let streamEnd = this.$fs.futureFromEvent(stream, "finish");
                stream.end();
                streamEnd.wait();
                this.$fs.chmod(triggerFile, "0777");
            }
            this.$logger.trace("Starting watch on killswitch %s", triggerFile);
            let watcherInitialized = new Future();
            gaze(triggerFile, function (err, watcher) {
                this.on("deleted", (filePath) => process.exit());
                if (err) {
                    watcherInitialized.throw(err);
                }
                else {
                    watcherInitialized.return(watcher);
                }
            });
            let watcher = watcherInitialized.wait();
            if (watcher) {
                this.watches[name] = watcher;
            }
        }).future()();
    }
    end(name) {
        let watcher = this.watches[name];
        delete this.watches[name];
        watcher.close();
    }
    dispose() {
        _(this.watches).keys().each(name => this.end(name));
    }
    static get killSwitchDir() {
        return path.join(os.tmpdir(), process.env.SUDO_USER || process.env.USER || process.env.USERNAME || '', "KillSwitches");
    }
    static makeKillSwitchFileName(name) {
        return path.join(CancellationService.killSwitchDir, name);
    }
}
class CancellationServiceDummy {
    dispose() {
    }
    begin(name) {
        return Future.fromResult();
    }
    end(name) {
    }
}
if (hostInfo.isWindows) {
    $injector.register("cancellation", CancellationService);
}
else {
    $injector.register("cancellation", CancellationServiceDummy);
}
