"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 bn_js_1 = __importDefault(require("bn.js"));
const util_1 = require("@polkadot/util");
const util_crypto_1 = require("@polkadot/util-crypto");
const create_1 = require("../../codec/create");
const U32_1 = __importDefault(require("../U32"));
exports.ENUMSET_SIZE = new bn_js_1.default(64);
const PREFIX_1BYTE = 0xef;
const PREFIX_2BYTE = 0xfc;
const PREFIX_4BYTE = 0xfd;
const PREFIX_8BYTE = 0xfe;
const MAX_1BYTE = new bn_js_1.default(PREFIX_1BYTE);
const MAX_2BYTE = new bn_js_1.default(1).shln(16);
const MAX_4BYTE = new bn_js_1.default(1).shln(32);
/**
 * @name AccountIndex
 * @description
 * A wrapper around an AccountIndex, which is a shortened, variable-length encoding
 * for an Account. We extends from [[U32]] to provide the number-like properties.
 */
class AccountIndex extends U32_1.default {
    constructor(registry, value = new bn_js_1.default(0)) {
        super(registry, AccountIndex.decodeAccountIndex(value));
    }
    /** @internal */
    static decodeAccountIndex(value) {
        if (value instanceof AccountIndex) {
            // `value.toBn()` on AccountIndex returns a pure BN (i.e. not an
            // AccountIndex), which has the initial `toString()` implementation.
            return value.toBn();
        }
        else if (util_1.isBn(value) || util_1.isNumber(value) || util_1.isHex(value) || util_1.isU8a(value)) {
            return value;
        }
        return AccountIndex.decodeAccountIndex(util_crypto_1.decodeAddress(value));
    }
    static calcLength(_value) {
        const value = util_1.bnToBn(_value);
        if (value.lte(MAX_1BYTE)) {
            return 1;
        }
        else if (value.lt(MAX_2BYTE)) {
            return 2;
        }
        else if (value.lt(MAX_4BYTE)) {
            return 4;
        }
        return 8;
    }
    static readLength(input) {
        const first = input[0];
        if (first === PREFIX_2BYTE) {
            return [1, 2];
        }
        else if (first === PREFIX_4BYTE) {
            return [1, 4];
        }
        else if (first === PREFIX_8BYTE) {
            return [1, 8];
        }
        return [0, 1];
    }
    static writeLength(input) {
        switch (input.length) {
            case 2: return new Uint8Array([PREFIX_2BYTE]);
            case 4: return new Uint8Array([PREFIX_4BYTE]);
            case 8: return new Uint8Array([PREFIX_8BYTE]);
            default: return new Uint8Array([]);
        }
    }
    /**
     * @description Compares the value of the input to see if there is a match
     */
    eq(other) {
        // shortcut for BN or Number, don't create an object
        if (util_1.isBn(other) || util_1.isNumber(other)) {
            return super.eq(other);
        }
        // convert and compare
        return super.eq(create_1.createType(this.registry, 'AccountIndex', other));
    }
    /**
     * @description Converts the Object to JSON, typically used for RPC transfers
     */
    toJSON() {
        return this.toString();
    }
    /**
     * @description Returns the string representation of the value
     */
    toString() {
        const length = AccountIndex.calcLength(this);
        return util_crypto_1.encodeAddress(this.toU8a().subarray(0, length));
    }
    /**
     * @description Returns the base runtime type name for this instance
     */
    toRawType() {
        return 'AccountIndex';
    }
}
exports.default = AccountIndex;
