"use strict";
// Copyright 2017-2020 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("@polkadot/util");
const defaults_1 = require("@polkadot/util/compact/defaults");
const utils_1 = require("./utils");
const Base_1 = __importDefault(require("./Base"));
/**
 * @name Compact
 * @description
 * A compact length-encoding codec wrapper. It performs the same function as Length, however
 * differs in that it uses a variable number of bytes to do the actual encoding. This is mostly
 * used by other types to add length-prefixed encoding, or in the case of wrapped types, taking
 * a number and making the compact representation thereof
 */
class Compact extends Base_1.default {
    constructor(registry, Type, value = 0) {
        super(registry, Compact.decodeCompact(registry, utils_1.typeToConstructor(registry, Type), value));
    }
    static with(Type) {
        return class extends Compact {
            constructor(registry, value) {
                super(registry, Type, value);
            }
        };
    }
    static stripLengthPrefix(u8a, bitLength = defaults_1.DEFAULT_BITLENGTH) {
        const [, value] = util_1.compactStripLength(u8a, bitLength);
        return value;
    }
    /** @internal */
    static decodeCompact(registry, Type, value) {
        if (value instanceof Compact) {
            return new Type(registry, value.raw);
        }
        else if (util_1.isString(value) || util_1.isNumber(value) || util_1.isBn(value)) {
            return new Type(registry, value);
        }
        const [, _value] = Compact.decodeU8a(value, new Type(registry, 0).bitLength());
        return new Type(registry, _value);
    }
    /**
     * @description Returns the number of bits in the value
     */
    bitLength() {
        return this.raw.bitLength();
    }
    /**
     * @description Compares the value of the input to see if there is a match
     */
    eq(other) {
        return this.raw.eq(other instanceof Compact
            ? other.raw
            : other);
    }
    /**
     * @description Returns the BN representation of the number
     */
    toBn() {
        return this.raw.toBn();
    }
    /**
     * @description Returns the number representation for the value
     */
    toNumber() {
        return this.raw.toNumber();
    }
    /**
     * @description Returns the base runtime type name for this instance
     */
    toRawType() {
        return `Compact<${this.raw.toRawType()}>`;
    }
    /**
     * @description Encodes the value as a Uint8Array as per the SCALE specifications
     * @param isBare true when the value has none of the type-specific prefixes (internal)
     */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    toU8a(isBare) {
        return Compact.encodeU8a(this.raw.toBn());
    }
    /**
     * @description Returns the embedded [[UInt]] or [[Moment]] value
     */
    unwrap() {
        return this.raw;
    }
}
exports.default = Compact;
/**
 * Prepend a Uint8Array with its compact length.
 *
 * @param u8a - The Uint8Array to be prefixed
 */
Compact.addLengthPrefix = util_1.compactAddLength;
Compact.decodeU8a = util_1.compactFromU8a;
Compact.encodeU8a = util_1.compactToU8a;
