"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 core_1 = require("@angular-devkit/core");
class UnknownActionException extends core_1.BaseException {
    constructor(action) { super(`Unknown action: "${action.kind}".`); }
}
exports.UnknownActionException = UnknownActionException;
let _id = 1;
class ActionList {
    constructor() {
        this._actions = [];
    }
    _action(action) {
        this._actions.push(Object.assign({
            id: _id++,
            parent: this._actions[this._actions.length - 1] || 0,
        }, action));
    }
    create(path, content) {
        this._action({ kind: 'c', path, content });
    }
    overwrite(path, content) {
        this._action({ kind: 'o', path, content });
    }
    rename(path, to) {
        this._action({ kind: 'r', path, to });
    }
    delete(path) {
        this._action({ kind: 'd', path });
    }
    optimize() {
        const actions = this._actions;
        const deleted = new Set();
        this._actions = [];
        // Handles files we create.
        for (let i = 0; i < actions.length; i++) {
            const iAction = actions[i];
            if (iAction.kind == 'c') {
                let path = iAction.path;
                let content = iAction.content;
                let toDelete = false;
                deleted.delete(path);
                for (let j = i + 1; j < actions.length; j++) {
                    const action = actions[j];
                    if (path == action.path) {
                        switch (action.kind) {
                            case 'c':
                                content = action.content;
                                actions.splice(j--, 1);
                                break;
                            case 'o':
                                content = action.content;
                                actions.splice(j--, 1);
                                break;
                            case 'r':
                                path = action.to;
                                actions.splice(j--, 1);
                                break;
                            case 'd':
                                toDelete = true;
                                actions.splice(j--, 1);
                                break;
                        }
                    }
                    if (toDelete) {
                        break;
                    }
                }
                if (!toDelete) {
                    this.create(path, content);
                }
                else {
                    deleted.add(path);
                }
            }
            else if (deleted.has(iAction.path)) {
                // DoNothing
            }
            else {
                switch (iAction.kind) {
                    case 'o':
                        this.overwrite(iAction.path, iAction.content);
                        break;
                    case 'r':
                        this.rename(iAction.path, iAction.to);
                        break;
                    case 'd':
                        this.delete(iAction.path);
                        break;
                }
            }
        }
    }
    push(action) { this._actions.push(action); }
    get(i) { return this._actions[i]; }
    has(action) {
        for (let i = 0; i < this._actions.length; i++) {
            const a = this._actions[i];
            if (a.id == action.id) {
                return true;
            }
            if (a.id > action.id) {
                return false;
            }
        }
        return false;
    }
    find(predicate) {
        return this._actions.find(predicate) || null;
    }
    forEach(fn, thisArg) {
        this._actions.forEach(fn, thisArg);
    }
    get length() { return this._actions.length; }
    [Symbol.iterator]() { return this._actions[Symbol.iterator](); }
}
exports.ActionList = ActionList;
function isContentAction(action) {
    return action.kind == 'c' || action.kind == 'o';
}
exports.isContentAction = isContentAction;
function isAction(action) {
    const kind = action && action.kind;
    return action !== null
        && typeof action.id == 'number'
        && typeof action.path == 'string'
        && (kind == 'c' || kind == 'o' || kind == 'r' || kind == 'd');
}
exports.isAction = isAction;
//# sourceMappingURL=data:application/json;base64,[encoded data, 12560 characters]