"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var tap_stream_1 = require("../../client/impl/frame/tap-stream");
var EnumConverter = /** @class */ (function () {
    function EnumConverter(mapping) {
        this.mapping = mapping;
    }
    EnumConverter.prototype.decode = function (value) {
        var literalValue = this.decodeToLiteral(value);
        var enumStringValue = this.mapping[literalValue];
        if (!enumStringValue) {
            throw new Error("Unknown litteral value " + literalValue + ".");
        }
        return literalValue;
    };
    EnumConverter.prototype.encode = function (value) {
        if (typeof value != "number") {
            throw Error("Illegal argument when encoding enum value. Expecting  number but found " + typeof value);
        }
        return this.encodeToLiteral(value);
    };
    return EnumConverter;
}());
exports.EnumConverter = EnumConverter;
var FixedSizeEnumConverter = /** @class */ (function (_super) {
    __extends(FixedSizeEnumConverter, _super);
    function FixedSizeEnumConverter(mapping, size) {
        if (size === void 0) { size = 1; }
        var _this = _super.call(this, mapping) || this;
        _this.mapping = mapping;
        _this.size = size;
        return _this;
    }
    FixedSizeEnumConverter.prototype.decodeToLiteral = function (value) {
        return tap_stream_1.TapStreamReader.fromArray(value).readU(this.size);
    };
    FixedSizeEnumConverter.prototype.encodeToLiteral = function (value) {
        return new tap_stream_1.TapStreamWriter(this.size).writeU(value, this.size).toBytes;
    };
    return FixedSizeEnumConverter;
}(EnumConverter));
exports.FixedSizeEnumConverter = FixedSizeEnumConverter;
var EnumListConverter = /** @class */ (function () {
    function EnumListConverter(size, mapping) {
        this.size = size;
        this.mapping = mapping;
    }
    EnumListConverter.prototype.decode = function (value) {
        var _this = this;
        var bits = this.decodeToLiteral(tap_stream_1.TapStreamReader.create(value));
        var results = [];
        var enumValues = Object.keys(this.mapping).filter(function (key) { return !isNaN(Number(_this.mapping[key])); });
        // console.log("numval", enumValues)
        for (var _i = 0, enumValues_1 = enumValues; _i < enumValues_1.length; _i++) {
            var enumName = enumValues_1[_i];
            var enumValue = this.mapping[enumName];
            var mask = parseInt(enumValue);
            if (mask == 0) {
                if (bits == 0) {
                    results.push(enumValue);
                }
            }
            else if ((bits & mask) == mask) {
                results.push(enumValue);
            }
        }
        return results;
    };
    EnumListConverter.prototype.encode = function (values) {
        var mask = 0;
        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
            var value = values_1[_i];
            if (typeof value != "number") {
                throw Error("Illegal argument when encoding enum value. Expecting number but found " + typeof value);
            }
            mask |= value;
        }
        var result = new tap_stream_1.TapStreamWriter(this.size).writeU(mask, this.size).toBytes;
        return result;
    };
    EnumListConverter.prototype.decodeToLiteral = function (stream) {
        return stream.readU(this.size);
    };
    return EnumListConverter;
}());
exports.EnumListConverter = EnumListConverter;
