"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const transactionFactory_1 = require("../../../../../utils/solidity/transactionFactory");
const Contracts_1 = require("../../../../../Contracts");
const token_math_1 = require("@melonproject/token-math");
const evm_1 = require("../../../../../utils/evm");
const Environment_1 = require("../../../../../utils/environment/Environment");
const isBuySell = (prices) => {
    if (!prices.length)
        return false;
    const first = prices[0];
    return (first.buy !== undefined && first.sell !== undefined);
};
const toHexString = (byteArray) => {
    return Array.from(byteArray, byte => `0${(byte & 0xff).toString(16)}`.slice(-2)).join('');
};
const splitArray = (arr, length) => {
    const groups = arr
        .map((e, i) => (i % length === 0 ? arr.slice(i, i + length) : null))
        .filter(e => e);
    return groups;
};
// If buy-sell prices are not explicity passed, assumes passed price to be sell
const prepareArgs = (environment, { prices, blockNumber: givenBlockNumber }) => __awaiter(this, void 0, void 0, function* () {
    environment.logger('debug', Environment_1.LogLevels.DEBUG, prices);
    const numberOfTokens = prices.length;
    const enhancedPrices = isBuySell(prices)
        ? prices
        : prices.map(p => ({
            buy: token_math_1.createPrice(p.quote, p.base),
            sell: p,
        }));
    const tokens = enhancedPrices.map(p => p.sell.base.token.address.toString());
    const baseBuy = enhancedPrices.map(p => `${token_math_1.toAtomic(p.buy)}`);
    const baseSell = enhancedPrices.map(p => `${token_math_1.toAtomic(p.sell)}`);
    const blockNumber = givenBlockNumber || (yield evm_1.getLatestBlock(environment)).number;
    // Generate and format compact data (Set to 0)
    // Formatting info: https://developer.kyber.network/docs/ReservesGuide/
    const zeroArray = splitArray(Array(numberOfTokens).fill(0), 14);
    const zeroCompactDataArray = zeroArray.map(v => `0x${toHexString(v)}`);
    const indices = Array.from(Array(zeroCompactDataArray.length).keys());
    return [
        tokens,
        baseBuy,
        baseSell,
        zeroCompactDataArray,
        zeroCompactDataArray,
        blockNumber,
        indices,
    ];
});
const setBaseRate = transactionFactory_1.transactionFactory('setBaseRate', Contracts_1.Contracts.ConversionRates, undefined, prepareArgs);
exports.setBaseRate = setBaseRate;
