"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());
    });
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const R = __importStar(require("ramda"));
const token_math_1 = require("@melonproject/token-math");
const randomString_1 = require("../../utils/helpers/randomString");
const beginSetup_1 = require("../../contracts/factory/transactions/beginSetup");
const completeSetup_1 = require("../../contracts/factory/transactions/completeSetup");
const createAccounting_1 = require("../../contracts/factory/transactions/createAccounting");
const createFeeManager_1 = require("../../contracts/factory/transactions/createFeeManager");
const createParticipation_1 = require("../../contracts/factory/transactions/createParticipation");
const createPolicyManager_1 = require("../../contracts/factory/transactions/createPolicyManager");
const createShares_1 = require("../../contracts/factory/transactions/createShares");
const createTrading_1 = require("../../contracts/factory/transactions/createTrading");
const createVault_1 = require("../../contracts/factory/transactions/createVault");
const getRoutes_1 = require("../../contracts/fund/hub/calls/getRoutes");
const requestInvestment_1 = require("../../contracts/fund/participation/transactions/requestInvestment");
const approve_1 = require("../../contracts/dependencies/token/transactions/approve");
const executeRequest_1 = require("../../contracts/fund/participation/transactions/executeRequest");
const Environment_1 = require("../../utils/environment/Environment");
const getTokenBySymbol_1 = require("../../utils/environment/getTokenBySymbol");
const DAY_IN_SECONDS = 60 * 60 * 24;
const setupInvestedTestFund = (environment) => __awaiter(this, void 0, void 0, function* () {
    const fundName = `test-fund-${randomString_1.randomString()}`;
    const debug = environment.logger('melon:protocol:tests:setupInvestedTestFund', Environment_1.LogLevels.DEBUG);
    debug('Setting up testfund', fundName);
    const { exchangeConfigs, melonContracts } = environment.deployment;
    const weth = getTokenBySymbol_1.getTokenBySymbol(environment, 'WETH');
    const mln = getTokenBySymbol_1.getTokenBySymbol(environment, 'MLN');
    const fees = [
        {
            feeAddress: melonContracts.fees.managementFee.toLowerCase(),
            feePeriod: token_math_1.toBI(0),
            feeRate: token_math_1.appendDecimals(weth, 0.02),
        },
        {
            feeAddress: melonContracts.fees.performanceFee.toLowerCase(),
            feePeriod: token_math_1.toBI(DAY_IN_SECONDS * 90),
            feeRate: token_math_1.appendDecimals(weth, 0.2),
        },
    ];
    yield beginSetup_1.beginSetup(environment, melonContracts.version, {
        defaultTokens: [weth, mln],
        exchangeConfigs,
        fees,
        fundName,
        nativeToken: weth,
        priceSource: melonContracts.priceSource,
        quoteToken: weth,
    });
    yield createAccounting_1.createAccounting(environment, melonContracts.version);
    yield createFeeManager_1.createFeeManager(environment, melonContracts.version);
    yield createParticipation_1.createParticipation(environment, melonContracts.version);
    yield createPolicyManager_1.createPolicyManager(environment, melonContracts.version);
    yield createShares_1.createShares(environment, melonContracts.version);
    yield createTrading_1.createTrading(environment, melonContracts.version);
    yield createVault_1.createVault(environment, melonContracts.version);
    const hubAddress = yield completeSetup_1.completeSetup(environment, melonContracts.version);
    const routes = yield getRoutes_1.getRoutes(environment, hubAddress);
    expect(R.keys(routes)).toEqual(expect.arrayContaining([
        'accountingAddress',
        'feeManagerAddress',
        'participationAddress',
        'policyManagerAddress',
        'priceSourceAddress',
        'registryAddress',
        'sharesAddress',
        'tradingAddress',
        'vaultAddress',
        'versionAddress',
    ]));
    const investmentAmount = token_math_1.createQuantity(weth, 1);
    yield approve_1.approve(environment, {
        howMuch: investmentAmount,
        spender: routes.participationAddress,
    });
    yield requestInvestment_1.requestInvestment(environment, routes.participationAddress, {
        investmentAmount,
    });
    yield executeRequest_1.executeRequest(environment, routes.participationAddress);
    debug('Testfund setup and invested', fundName, routes);
    return Object.assign({}, routes, { hubAddress });
});
exports.setupInvestedTestFund = setupInvestedTestFund;
