"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const gasLimits_js_1 = require("../../gasLimits.js");
const commonTypes_1 = require("../commonTypes");
const genesisProtocol_1 = require("../wrappers/genesisProtocol");
/* tslint:disable:no-var-requires */
const env = require("env-variable")();
/**
 * Migration callback
 */
exports.arcJsDeployer = (web3, artifacts, deployer) => {
    // so Utils.getWeb3 can find it
    global.web3 = web3;
    const network = env.arcjs_network || "ganache";
    const internalFoundersConfigLocation = "../../migrations/founders.json";
    const foundersConfig = require(internalFoundersConfigLocation).founders;
    const customFoundersConfigLocation = env.arcjs_foundersConfigurationLocation || internalFoundersConfigLocation;
    if (internalFoundersConfigLocation !== customFoundersConfigLocation) {
        console.log(`merging custom founders from ${customFoundersConfigLocation}`);
        const customFoundersConfig = require(customFoundersConfigLocation).founders;
        // merge the two
        Object.assign(foundersConfig, customFoundersConfig);
    }
    const founders = foundersConfig[network];
    if (!founders || (founders.length === 0)) {
        throw new Error(`no founders were given for the network: ${network}`);
    }
    const gasAmount = gasLimits_js_1.computeGasLimit(founders.length);
    console.log(`Deploying to ${network}, gasLimit: ${gasAmount},  ${founders.length} founders`);
    /**
     * Truffle Solidity artifact wrappers
     */
    const AbsoluteVote = artifacts.require("AbsoluteVote.sol");
    const Avatar = artifacts.require("Avatar.sol");
    const ContributionReward = artifacts.require("ContributionReward.sol");
    const DaoCreator = artifacts.require("DaoCreator.sol");
    // ExecutableTest is used only by tests
    const ExecutableTest = artifacts.require("ExecutableTest.sol");
    const GlobalConstraintRegistrar = artifacts.require("GlobalConstraintRegistrar.sol");
    const SchemeRegistrar = artifacts.require("SchemeRegistrar.sol");
    const SimpleICO = artifacts.require("SimpleICO.sol");
    const TokenCapGC = artifacts.require("TokenCapGC.sol");
    const UController = artifacts.require("UController.sol");
    const UpgradeScheme = artifacts.require("UpgradeScheme.sol");
    const VestingScheme = artifacts.require("VestingScheme.sol");
    const VoteInOrganizationScheme = artifacts.require("VoteInOrganizationScheme.sol");
    const GenesisProtocol = artifacts.require("GenesisProtocol.sol");
    const ControllerCreator = artifacts.require("ControllerCreator.sol");
    /**
     * Apparently we must wrap the first deploy call in a `then` to avoid
     * what seems to be race conditions during deployment.
     */
    deployer.deploy(ControllerCreator).then(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
        /**
         *  Genesis DAO parameters,  FOR TESTING PURPOSES ONLY
         */
        const orgName = "Genesis Alpha";
        const tokenName = "Genesis Alpha";
        const tokenSymbol = "GDT";
        const orgNativeTokenFee = 0;
        const defaultVotingMachineParams = yield genesisProtocol_1.GetDefaultGenesisProtocolParameters();
        const schemeRegistrarPermissions = commonTypes_1.SchemePermissions.toString(commonTypes_1.DefaultSchemePermissions.SchemeRegistrar);
        const globalConstraintRegistrarPermissions = commonTypes_1.SchemePermissions.toString(commonTypes_1.DefaultSchemePermissions.GlobalConstraintRegistrar);
        const upgradeSchemePermissions = commonTypes_1.SchemePermissions.toString(commonTypes_1.DefaultSchemePermissions.UpgradeScheme);
        const contributionRewardPermissions = commonTypes_1.SchemePermissions.toString(commonTypes_1.DefaultSchemePermissions.ContributionReward);
        const genesisProtocolPermissions = commonTypes_1.SchemePermissions.toString(commonTypes_1.DefaultSchemePermissions.GenesisProtocol);
        const controllerCreator = yield ControllerCreator.deployed();
        yield deployer.deploy(DaoCreator, controllerCreator.address);
        const daoCreatorInst = yield DaoCreator.deployed(controllerCreator.address);
        yield deployer.deploy(UController, { gas: gasAmount });
        const universalControllerInst = yield UController.deployed();
        /**
         * Create the Genesis DAO
         */
        const tx = yield daoCreatorInst.forgeOrg(orgName, tokenName, tokenSymbol, founders.map((f) => f.address), founders.map((f) => web3.toWei(f.tokens)), founders.map((f) => web3.toWei(f.reputation)), universalControllerInst.address, web3.toWei(100000000), // token cap of one hundred million GEN, in Wei
        { gas: gasAmount });
        const AvatarInst = yield Avatar.at(tx.logs[0].args._avatar);
        let genTokenAddress;
        if (network !== "live") {
            genTokenAddress = yield AvatarInst.nativeToken();
            console.log(`using native token for staking on network != "live" at: ${genTokenAddress}`);
        }
        else {
            // the "real" live ETH GEN token
            genTokenAddress = "0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf";
            console.log(`!! using global GEN token staking on network == "live" at: ${genTokenAddress}`);
        }
        /**
         * The voting machine.  GenesisProtocol must be deployed as a scheme if it is
         * to be used by schemes as a voting machine, which is what all of the
         * Genesis schemes do.
         */
        yield deployer.deploy(GenesisProtocol, genTokenAddress);
        const genesisProtocolInst = yield GenesisProtocol.deployed();
        /**
         * The rest of the Genesis DAO's schemes
         */
        yield deployer.deploy(SchemeRegistrar);
        const schemeRegistrarInst = yield SchemeRegistrar.deployed();
        yield deployer.deploy(UpgradeScheme);
        const upgradeSchemeInst = yield UpgradeScheme.deployed();
        yield deployer.deploy(GlobalConstraintRegistrar);
        const globalConstraintRegistrarInst = yield GlobalConstraintRegistrar.deployed();
        yield deployer.deploy(ContributionReward);
        const contributionRewardInst = yield ContributionReward.deployed();
        /**
         * Set/get the GenesisProtocol voting parameters that will be used as defaults
         * for the schemes' voting machine as we add the schemes to the Genesis DAO, below.
         */
        const genesisProtocolParams = yield genesisProtocolInst.getParametersHash([
            defaultVotingMachineParams.preBoostedVoteRequiredPercentage,
            defaultVotingMachineParams.preBoostedVotePeriodLimit,
            defaultVotingMachineParams.boostedVotePeriodLimit,
            defaultVotingMachineParams.thresholdConstA,
            defaultVotingMachineParams.thresholdConstB,
            defaultVotingMachineParams.minimumStakingFee,
            defaultVotingMachineParams.quietEndingPeriod,
            defaultVotingMachineParams.proposingRepRewardConstA,
            defaultVotingMachineParams.proposingRepRewardConstB,
            defaultVotingMachineParams.stakerFeeRatioForVoters,
            defaultVotingMachineParams.votersReputationLossRatio,
            defaultVotingMachineParams.votersGainRepRatioFromLostRep,
            defaultVotingMachineParams.daoBountyConst,
            defaultVotingMachineParams.daoBountyLimit,
        ]);
        yield genesisProtocolInst.setParameters([
            defaultVotingMachineParams.preBoostedVoteRequiredPercentage,
            defaultVotingMachineParams.preBoostedVotePeriodLimit,
            defaultVotingMachineParams.boostedVotePeriodLimit,
            defaultVotingMachineParams.thresholdConstA,
            defaultVotingMachineParams.thresholdConstB,
            defaultVotingMachineParams.minimumStakingFee,
            defaultVotingMachineParams.quietEndingPeriod,
            defaultVotingMachineParams.proposingRepRewardConstA,
            defaultVotingMachineParams.proposingRepRewardConstB,
            defaultVotingMachineParams.stakerFeeRatioForVoters,
            defaultVotingMachineParams.votersReputationLossRatio,
            defaultVotingMachineParams.votersGainRepRatioFromLostRep,
            defaultVotingMachineParams.daoBountyConst,
            defaultVotingMachineParams.daoBountyLimit,
        ]);
        /**
         * Set/get the Genesis DAO's scheme parameters, using the GenesisProtocol voting machine
         * parameters that we just obtained above.
         */
        yield schemeRegistrarInst.setParameters(genesisProtocolParams, genesisProtocolParams, genesisProtocolInst.address);
        const schemeRegisterParams = yield schemeRegistrarInst.getParametersHash(genesisProtocolParams, genesisProtocolParams, genesisProtocolInst.address);
        yield globalConstraintRegistrarInst.setParameters(genesisProtocolParams, genesisProtocolInst.address);
        const schemeGCRegisterParams = yield globalConstraintRegistrarInst.getParametersHash(genesisProtocolParams, genesisProtocolInst.address);
        yield upgradeSchemeInst.setParameters(genesisProtocolParams, genesisProtocolInst.address);
        const schemeUpgradeParams = yield upgradeSchemeInst.getParametersHash(genesisProtocolParams, genesisProtocolInst.address);
        yield contributionRewardInst.setParameters(orgNativeTokenFee, genesisProtocolParams, genesisProtocolInst.address);
        const contributionRewardParams = yield contributionRewardInst.getParametersHash(orgNativeTokenFee, genesisProtocolParams, genesisProtocolInst.address);
        /**
         * Register the schemes with the Genesis DAO
         */
        const schemesArray = [
            schemeRegistrarInst.address,
            globalConstraintRegistrarInst.address,
            upgradeSchemeInst.address,
            contributionRewardInst.address,
            genesisProtocolInst.address
        ];
        const paramsArray = [
            schemeRegisterParams,
            schemeGCRegisterParams,
            schemeUpgradeParams,
            contributionRewardParams,
            genesisProtocolParams
        ];
        const permissionArray = [
            schemeRegistrarPermissions,
            globalConstraintRegistrarPermissions,
            upgradeSchemePermissions,
            contributionRewardPermissions,
            genesisProtocolPermissions,
        ];
        yield daoCreatorInst.setSchemes(AvatarInst.address, schemesArray, paramsArray, permissionArray);
        /**
         * Deploy the other universal schemes, voting machines and global constraints
         */
        yield deployer.deploy(AbsoluteVote);
        yield deployer.deploy(SimpleICO);
        yield deployer.deploy(TokenCapGC);
        yield deployer.deploy(VestingScheme);
        yield deployer.deploy(VoteInOrganizationScheme);
        if (network !== "live") {
            yield deployer.deploy(ExecutableTest);
        }
    }));
};
//# sourceMappingURL=2_deploy_organization.js.map