"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const ethers_1 = require("ethers");
const index_1 = require("./index");
function getLiquidatableUsers(sdk, poolUsers, pool, chainLiquidationConfig) {
    return __awaiter(this, void 0, void 0, function* () {
        const users = [];
        for (const user of poolUsers) {
            const userAssets = yield sdk.contracts.PoolLens.callStatic.getPoolAssetsByUser(pool.comptroller, user.account);
            const userWithAssets = Object.assign(Object.assign({}, user), { debt: [], collateral: [], assets: userAssets });
            const encodedLiquidationTX = yield (0, index_1.getPotentialLiquidation)(sdk, userWithAssets, pool.closeFactor, pool.liquidationIncentive, chainLiquidationConfig);
            if (encodedLiquidationTX !== null)
                users.push(encodedLiquidationTX);
        }
        return users;
    });
}
function gatherLiquidations(sdk, pools, chainLiquidationConfig) {
    return __awaiter(this, void 0, void 0, function* () {
        const liquidations = [];
        const erroredPools = [];
        for (const pool of pools) {
            const poolUsers = pool.users.slice().sort((a, b) => {
                const right = ethers_1.BigNumber.from(b.totalBorrow);
                const left = ethers_1.BigNumber.from(a.totalBorrow);
                if (right.gt(left))
                    return 1;
                if (right.lt(left))
                    return -1;
                return 0;
            });
            try {
                const liquidatableUsers = yield getLiquidatableUsers(sdk, poolUsers, pool, chainLiquidationConfig);
                if (liquidatableUsers.length > 0) {
                    liquidations.push({
                        comptroller: pool.comptroller,
                        liquidations: liquidatableUsers
                    });
                }
            }
            catch (e) {
                erroredPools.push({
                    msg: "Error while fetching liquidatable users " + e.stack,
                    comptroller: pool.comptroller,
                    error: e
                });
            }
        }
        return [liquidations, erroredPools];
    });
}
exports.default = gatherLiquidations;
