"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 create_1 = require("../../codec/create");
const U32_1 = __importDefault(require("../U32"));
const CID_AURA = 0x61727561; // 'aura'
exports.CID_AURA = CID_AURA;
const CID_BABE = 0x45424142; // 'BABE'
exports.CID_BABE = CID_BABE;
const CID_GRPA = 0x4b4e5246; // 'FRNK' (don't ask, used to be afg1)
exports.CID_GRPA = CID_GRPA;
/**
 * @name ConsensusEngineId
 * @description
 * A 4-byte identifier (actually a [u8; 4]) identifying the engine, e.g. for Aura it would be [b'a', b'u', b'r', b'a']
 */
class ConsensusEngineId extends U32_1.default {
    static idToString(input) {
        return util_1.bnToBn(input)
            .toArray('le')
            .map((code) => String.fromCharCode(code))
            .join('');
    }
    static stringToId(input) {
        return input
            .split('')
            .reverse()
            .reduce((result, char) => (result * 256) + char.charCodeAt(0), 0);
    }
    /**
     * @description `true` if the engine matches aura
     */
    get isAura() {
        return this.eq(CID_AURA);
    }
    /**
     * @description `true` is the engine matches babe
     */
    get isBabe() {
        return this.eq(CID_BABE);
    }
    /**
     * @description `true` is the engine matches grandpa
     */
    get isGrandpa() {
        return this.eq(CID_GRPA);
    }
    getAuraAuthor(bytes, sessionValidators) {
        return sessionValidators[create_1.createType(this.registry, 'RawAuraPreDigest', bytes.toU8a(true))
            .slotNumber
            .mod(new bn_js_1.default(sessionValidators.length))
            .toNumber()];
    }
    getBabeAuthor(bytes, sessionValidators) {
        const digest = create_1.createType(this.registry, 'RawBabePreDigestCompat', bytes.toU8a(true));
        return sessionValidators[digest.value.toNumber()];
    }
    /**
     * @description From the input bytes, decode into an author
     */
    extractAuthor(bytes, sessionValidators) {
        var _a;
        if ((_a = sessionValidators) === null || _a === void 0 ? void 0 : _a.length) {
            if (this.isAura) {
                return this.getAuraAuthor(bytes, sessionValidators);
            }
            else if (this.isBabe) {
                return this.getBabeAuthor(bytes, sessionValidators);
            }
        }
        return undefined;
    }
    /**
     * @description Override the default toString to return a 4-byte string
     */
    toString() {
        return ConsensusEngineId.idToString(this);
    }
}
exports.default = ConsensusEngineId;
