"use strict";
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
Object.defineProperty(exports, "__esModule", { value: true });
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const types_1 = require("../../types");
const util_1 = require("../util");
function createDerivedLatest(api, [[hasBabe, epochDuration, sessionsPerEra], { currentIndex, currentEra, validatorCount }, [currentSlot, epochIndex, epochOrGenesisStartSlot, currentEraStartSessionIndex]]) {
    const epochStartSlot = epochIndex.mul(epochDuration).add(epochOrGenesisStartSlot);
    const sessionProgress = currentSlot.sub(epochStartSlot);
    const eraProgress = currentIndex.sub(currentEraStartSessionIndex).mul(epochDuration).add(sessionProgress);
    return {
        currentEra,
        currentIndex,
        eraLength: types_1.createType(api.registry, 'BlockNumber', sessionsPerEra.mul(epochDuration)),
        eraProgress: types_1.createType(api.registry, 'BlockNumber', eraProgress),
        isEpoch: hasBabe,
        sessionLength: epochDuration,
        sessionsPerEra,
        sessionProgress: types_1.createType(api.registry, 'BlockNumber', sessionProgress),
        validatorCount
    };
}
function infoLatestAura(api) {
    return api.derive.session.indexes().pipe(operators_1.map((indexes) => {
        var _a;
        return createDerivedLatest(api, [
            [false, types_1.createType(api.registry, 'u64', 1), ((_a = api.consts.staking) === null || _a === void 0 ? void 0 : _a.sessionsPerEra) || types_1.createType(api.registry, 'SessionIndex', 1)],
            indexes,
            [types_1.createType(api.registry, 'u64', 1), types_1.createType(api.registry, 'u64', 1), types_1.createType(api.registry, 'u64', 1), types_1.createType(api.registry, 'SessionIndex', 1)]
        ]);
    }));
}
function infoLatestBabe(api) {
    return rxjs_1.combineLatest([
        api.derive.session.indexes(),
        api.queryMulti([
            api.query.babe.currentSlot,
            api.query.babe.epochIndex,
            api.query.babe.genesisSlot,
            api.query.staking.currentEraStartSessionIndex
        ])
    ]).pipe(operators_1.map(([indexes, slots]) => createDerivedLatest(api, [
        [true, api.consts.babe.epochDuration, api.consts.staking.sessionsPerEra],
        indexes,
        slots
    ])));
}
/**
 * @description Retrieves all the session and era info and calculates specific values on it as the length of the session and eras
 */
function info(api) {
    const query = api.consts.babe
        ? infoLatestBabe // 2.x with Babe
        : infoLatestAura; // 2.x with Aura (not all info there)
    return util_1.memo(() => query(api));
}
exports.info = info;
