"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sinon_1 = __importDefault(require("sinon"));
const api_1 = require("@polkadot/api");
const src_1 = require("../../../src/");
const factory_1 = require("../../../src/factory");
const big_js_1 = __importDefault(require("big.js"));
const chai_1 = require("chai");
const monetary_js_1 = require("@interlay/monetary-js");
describe("DefaultLoansAPI", () => {
    let api;
    let stubbedAssetRegistry;
    let loansApi;
    const testGovernanceCurrency = monetary_js_1.Interlay;
    before(() => {
        api = new api_1.ApiPromise();
        // disconnect immediately to avoid printing errors
        // we only need the instance to create variables
        api.disconnect();
        api.registerTypes(factory_1.getAPITypes());
    });
    beforeEach(() => {
        stubbedAssetRegistry = sinon_1.default.createStubInstance(src_1.DefaultAssetRegistryAPI);
        const transactionAPI = new src_1.DefaultTransactionAPI(api);
        loansApi = new src_1.DefaultLoansAPI(api, stubbedAssetRegistry, transactionAPI);
    });
    describe("getLendPositionsOfAccount", () => {
        // TODO: add tests
    });
    describe("getBorrowPositionsOfAccount", () => {
        // TODO: add tests
    });
    describe("getLoanAssets", () => {
        // TODO: add tests
    });
    describe("_calculateAnnualizedRewardAmount", () => {
        it("should calculate annulized amount correctly", () => {
            const secsPerYear = 365 * 24 * 60 * 60;
            // this can and will fail if block times change
            // (and that's a good thing)
            const assumedBlockDurationSecs = 12;
            const amountPerBlock = big_js_1.default(0.042);
            const expectedRewardAmount = amountPerBlock.mul(secsPerYear).div(assumedBlockDurationSecs);
            const actualRewardAmount = loansApi._calculateAnnualizedRewardAmount(amountPerBlock, assumedBlockDurationSecs * 1000);
            chai_1.expect(actualRewardAmount.eq(expectedRewardAmount)).to.eq(true, `Expected result to be equal to ${expectedRewardAmount.toString()} but was: ${actualRewardAmount.toString()}`);
        });
        it("should throw if blockTimeMs is zero", () => {
            chai_1.expect(() => loansApi._calculateAnnualizedRewardAmount(big_js_1.default(1), 0)).to.throw("Division by zero");
        });
        it("should return zero if reward per block is zero", () => {
            const actualRewardAmount = loansApi._calculateAnnualizedRewardAmount(big_js_1.default(0), 12 * 1000);
            chai_1.expect(actualRewardAmount.toNumber()).to.be.eq(0);
        });
    });
    describe("_calculateLiquidityAndCapacityAmounts", () => {
        const testUnderlying = monetary_js_1.Polkadot;
        const testExchangeRate = big_js_1.default(4.2);
        const testTotalIssuance = new monetary_js_1.MonetaryAmount(testUnderlying, 100000);
        const testTotalBorrows = new monetary_js_1.MonetaryAmount(testUnderlying, 100);
        const testIssuanceAtomicAmount = testTotalIssuance.toBig(0);
        const testBorrowsAtomicAmount = testTotalBorrows.toBig(0);
        it("should calculate amounts as expected", () => {
            const expectedTotalLiquidityAmount = testTotalIssuance.mul(testExchangeRate);
            const expectedAvailableCapacityAmount = expectedTotalLiquidityAmount.sub(testTotalBorrows);
            const [actualTotalLiquidity, actualAvailableCapacity] = loansApi._calculateLiquidityAndCapacityAmounts(testUnderlying, testIssuanceAtomicAmount, testBorrowsAtomicAmount, testExchangeRate);
            chai_1.expect(actualTotalLiquidity.toString()).to.be.eq(expectedTotalLiquidityAmount.toString());
            chai_1.expect(actualAvailableCapacity.toString()).to.be.eq(expectedAvailableCapacityAmount.toString());
        });
        it("should return zero total liquidity if exchange rate is zero", () => {
            const zeroExchangeRate = big_js_1.default(0);
            const [actualTotalLiquidity] = loansApi._calculateLiquidityAndCapacityAmounts(testUnderlying, testIssuanceAtomicAmount, testBorrowsAtomicAmount, zeroExchangeRate);
            chai_1.expect(actualTotalLiquidity.toBig().toNumber()).to.eq(0);
        });
        it("should return zero total liquidity if total issuance is zero", () => {
            const zeroIssuance = big_js_1.default(0);
            const [actualTotalLiquidity] = loansApi._calculateLiquidityAndCapacityAmounts(testUnderlying, zeroIssuance, testBorrowsAtomicAmount, testExchangeRate);
            chai_1.expect(actualTotalLiquidity.toBig().toNumber()).to.eq(0);
        });
        it("should return zero available capacity if borrow is equal to issuance times exchange rate", () => {
            const borrowAll = testTotalIssuance.mul(testExchangeRate);
            const borrowAllAtomicAmount = borrowAll.toBig(0);
            const [_, actualAvailableCapacity] = loansApi._calculateLiquidityAndCapacityAmounts(testUnderlying, testIssuanceAtomicAmount, borrowAllAtomicAmount, testExchangeRate);
            chai_1.expect(actualAvailableCapacity.toBig().toNumber()).to.eq(0);
        });
    });
    describe("_getSubsidyReward", () => {
        it("should return MonetaryAmount as expected", () => {
            const testAmountAtomic = 42e10;
            const expectedAmount = src_1.newMonetaryAmount(testAmountAtomic, testGovernanceCurrency);
            const actualReward = loansApi._getSubsidyReward(big_js_1.default(testAmountAtomic), testGovernanceCurrency);
            chai_1.expect(actualReward).to.not.be.null;
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            chai_1.expect(expectedAmount.toBig().eq(actualReward.toBig())).to.be.eq(true, `Expected total amount (atomic value) to equal ${expectedAmount.toString(true)} 
                but was: ${actualReward === null || actualReward === void 0 ? void 0 : actualReward.toString(true)}`);
            chai_1.expect(actualReward === null || actualReward === void 0 ? void 0 : actualReward.currency).to.eq(testGovernanceCurrency);
        });
        it("should return null if the amount is zero", () => {
            chai_1.expect(loansApi._getSubsidyReward(big_js_1.default(0), testGovernanceCurrency)).to.be.null;
        });
    });
});
//# sourceMappingURL=loans.test.js.map