"use strict";
var Table = require('cli-table');
var IVT_Property;
(function (IVT_Property) {
    IVT_Property[IVT_Property["V"] = 0] = "V";
    IVT_Property[IVT_Property["dV"] = 1] = "dV";
    IVT_Property[IVT_Property["V_S"] = 2] = "V_S";
    IVT_Property[IVT_Property["dV_S"] = 3] = "dV_S";
})(IVT_Property || (IVT_Property = {}));
var IVT = (function () {
    function IVT() {
        this.entries = [];
        this.initTable();
    }
    IVT.prototype.addEntry = function (property, M, S) {
        var ivtEntry;
        var concreteEntry;
        var symbolicEntry;
        ivtEntry = {};
        concreteEntry = M.hasProperty(property);
        symbolicEntry = S.hasProperty(property);
        if (!concreteEntry.hasProperty) {
            throw new Error(IVT.ERROR_PREFIX + 'unable to find property "' + property + '" in the concrete memory');
        }
        if (!symbolicEntry.hasProperty) {
            throw new Error(IVT.ERROR_PREFIX + 'unable to find property "' + property + '" in the symbolic memory');
        }
        ivtEntry.name = property;
        ivtEntry.attr = {};
        ivtEntry.attr.V = concreteEntry.content;
        ivtEntry.attr.V_S = symbolicEntry.content;
        this.entries.push(ivtEntry);
        this.addEntryToTable(1, ivtEntry);
    };
    IVT.prototype.update = function (iteration, M, S) {
        var property;
        var concreteEntry;
        var symbolicEntry;
        if (iteration === 2) {
            for (var k = 0; k < this.entries.length; k++) {
                property = this.entries[k].name;
                concreteEntry = M.hasProperty(property);
                symbolicEntry = S.hasProperty(property);
                if (!concreteEntry.hasProperty) {
                    throw new Error(IVT.ERROR_PREFIX + 'unable to find property "' + property + '" in the concrete memory');
                }
                if (!symbolicEntry.hasProperty) {
                    throw new Error(IVT.ERROR_PREFIX + 'unable to find property "' + property + '" in the symbolic memory');
                }
                this.entries[k].attr.dV = concreteEntry.content - this.entries[k].attr.V;
                this.entries[k].attr.dV_S = symbolicEntry.content + '-' + this.entries[k].attr.V_S;
                this.entries[k].attr.V = concreteEntry.content;
                this.addEntryToTable(iteration, this.entries[k]);
            }
        }
        else {
            var dV;
            var k;
            k = this.entries.length;
            while (k--) {
                property = this.entries[k].name;
                concreteEntry = M.hasProperty(property);
                if (!concreteEntry.hasProperty) {
                    throw new Error(IVT.ERROR_PREFIX + 'unable to find property "' + property + '" in the concrete memory');
                }
                dV = concreteEntry.content - this.entries[k].attr.V;
                if (dV !== this.entries[k].attr.dV) {
                    this.entries.splice(k, 1);
                }
                else {
                    this.entries[k].attr.V = concreteEntry.content;
                    this.addEntryToTable(iteration, this.entries[k]);
                }
            }
        }
    };
    IVT.prototype.initTable = function () {
        var headTable;
        headTable = {
            head: ['It.', 'Prop.', 'V', 'dV', 'V_S', 'dV_S'],
            colWidths: [8, 10, 20, 20, 20, 20]
        };
        this.table = new Table(headTable);
    };
    IVT.prototype.addEntryToTable = function (iteration, ivtEntry) {
        this.table.push([
            iteration,
            ivtEntry.name,
            (ivtEntry.attr.V === undefined)
                ? 'undefined'
                : ivtEntry.attr.V,
            (ivtEntry.attr.dV === undefined)
                ? 'undefined'
                : ivtEntry.attr.dV,
            (ivtEntry.attr.V_S === undefined)
                ? 'undefined'
                : ivtEntry.attr.V_S,
            (ivtEntry.attr.dV_S === undefined)
                ? 'undefined'
                : ivtEntry.attr.dV_S
        ]);
    };
    IVT.prototype.toString = function () {
        return this.table.toString();
    };
    IVT.ERROR_PREFIX = '[IVT] Exception. Reason: ';
    return IVT;
}());
module.exports = IVT;
