"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
const Observable_1 = require("rxjs/Observable");
require("rxjs/add/observable/concat");
require("rxjs/add/observable/empty");
require("rxjs/add/observable/merge");
require("rxjs/add/observable/of");
require("rxjs/add/operator/do");
require("rxjs/add/operator/map");
require("rxjs/add/operator/reduce");
const exception_1 = require("../exception/exception");
const update_buffer_1 = require("../utility/update-buffer");
const sink_1 = require("./sink");
class VirtualFileSystemSink extends sink_1.SimpleSinkBase {
    constructor(_host, _force = false) {
        super();
        this._host = _host;
        this._force = _force;
        this._filesToDelete = new Set();
        this._filesToRename = new Set();
        this._filesToCreate = new Map();
        this._filesToUpdate = new Map();
    }
    _validateCreateAction(action) {
        return this._force ? Observable_1.Observable.empty() : super._validateCreateAction(action);
    }
    _readFile(p) {
        const maybeCreate = this._filesToCreate.get(p);
        if (maybeCreate) {
            return Observable_1.Observable.of(maybeCreate);
        }
        const maybeUpdate = this._filesToUpdate.get(p);
        if (maybeUpdate) {
            return Observable_1.Observable.of(maybeUpdate);
        }
        throw new exception_1.FileDoesNotExistException(p);
    }
    _validateFileExists(p) {
        if (this._filesToCreate.has(p) || this._filesToUpdate.has(p)) {
            return Observable_1.Observable.of(true);
        }
        else if (this._filesToDelete.has(p)) {
            return Observable_1.Observable.of(false);
        }
        else {
            return this._host.exists(p);
        }
    }
    _overwriteFile(path, content) {
        this._filesToUpdate.set(path, new update_buffer_1.UpdateBuffer(content));
        return Observable_1.Observable.empty();
    }
    _createFile(path, content) {
        this._filesToCreate.set(path, new update_buffer_1.UpdateBuffer(content));
        return Observable_1.Observable.empty();
    }
    _renameFile(from, to) {
        this._filesToRename.add([from, to]);
        return this._readFile(from)
            .do(buffer => this._filesToCreate.set(to, buffer))
            .do(() => this._filesToDelete.add(from))
            .map(() => { });
    }
    _deleteFile(path) {
        if (this._filesToCreate.has(path)) {
            this._filesToCreate.delete(path);
            this._filesToUpdate.delete(path);
        }
        else {
            this._filesToDelete.add(path);
        }
        return Observable_1.Observable.empty();
    }
    _done() {
        // Really commit everything to the actual filesystem.
        return Observable_1.Observable.concat(Observable_1.Observable.from([...this._filesToDelete.values()])
            .concatMap(path => this._host.delete(path)), Observable_1.Observable.from([...this._filesToCreate.entries()])
            .concatMap(([path, buffer]) => this._host.write(path, buffer.generate())), Observable_1.Observable.from([...this._filesToRename.entries()])
            .concatMap(([_, [path, to]]) => this._host.rename(path, to)), Observable_1.Observable.from([...this._filesToUpdate.entries()])
            .concatMap(([path, buffer]) => this._host.write(path, buffer.generate()))).reduce(() => { });
    }
}
exports.VirtualFileSystemSink = VirtualFileSystemSink;
//# sourceMappingURL=data:application/json;base64,[encoded data, 9884 characters]