"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const bignumber_js_1 = require("bignumber.js");
const contractWrapperFactory_1 = require("../contractWrapperFactory");
const schemeWrapperBase_1 = require("../schemeWrapperBase");
const utilsInternal_1 = require("../utilsInternal");
const web3EventService_1 = require("../web3EventService");
class FixedReputationAllocationWrapper extends schemeWrapperBase_1.SchemeWrapperBase {
    constructor() {
        super(...arguments);
        this.name = "FixedReputationAllocation";
        this.friendlyName = "Fixed Reputation Allocation";
        this.factory = exports.FixedReputationAllocationFactory;
    }
    initialize(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const avatar = yield this.getAvatar();
            if (!utilsInternal_1.UtilsInternal.isNullAddress(avatar)) {
                throw new Error("you can only call initialize once");
            }
            if (!options.avatarAddress) {
                throw new Error("avatarAddress is not defined");
            }
            if (!options.redeemEnableTime) {
                throw new Error("redeemEnableTime is not defined");
            }
            if (!options.reputationReward) {
                throw new Error("reputationReward is not defined");
            }
            const reputationReward = new bignumber_js_1.default(options.reputationReward);
            if (reputationReward.lte(0)) {
                throw new Error("reputationReward must be greater than zero");
            }
            this.logContractFunctionCall("FixedReputationAllocation.initialize", options);
            return this.wrapTransactionInvocation("FixedReputationAllocation.initialize", options, this.contract.initialize, [
                options.avatarAddress,
                options.reputationReward,
                options.redeemEnableTime.getTime() / 1000,
            ]);
        });
    }
    redeem(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            yield this.validateEnabled(true);
            const now = yield utilsInternal_1.UtilsInternal.lastBlockDate();
            const redeemEnableTime = yield this.getRedeemEnableTime();
            if (now <= redeemEnableTime) {
                throw new Error(`nothing can be redeemed until after ${redeemEnableTime}`);
            }
            if (!options.beneficiaryAddress) {
                throw new Error("beneficiaryAddress is not defined");
            }
            this.logContractFunctionCall("FixedReputationAllocation.redeem", options);
            return this.wrapTransactionInvocation("FixedReputationAllocation.redeem", options, this.contract.redeem, [options.beneficiaryAddress]);
        });
    }
    addBeneficiary(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.beneficiaryAddress) {
                throw new Error("beneficiaryAddress is not defined");
            }
            yield this.validateEnabled(false);
            this.logContractFunctionCall("FixedReputationAllocation.addBeneficiary", options);
            return this.wrapTransactionInvocation("FixedReputationAllocation.addBeneficiary", options, this.contract.addBeneficiary, [options.beneficiaryAddress]);
        });
    }
    addBeneficiaries(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.beneficiaryAddresses || !options.beneficiaryAddresses.length) {
                throw new Error("beneficiaryAddresses is empty or not defined");
            }
            yield this.validateEnabled(false);
            this.logContractFunctionCall("FixedReputationAllocation.addBeneficiaries", options);
            return this.wrapTransactionInvocation("FixedReputationAllocation.addBeneficiaries", options, this.contract.addBeneficiaries, [options.beneficiaryAddresses]);
        });
    }
    setEnabled(options = {}) {
        this.logContractFunctionCall("FixedReputationAllocation.enable", options);
        return this.wrapTransactionInvocation("FixedReputationAllocation.enable", options, this.contract.enable, []);
    }
    /**
     * Get a promise of the first date/time when anything can be redeemed
     */
    getRedeemEnableTime() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.logContractFunctionCall("FixedReputationAllocation.redeemEnableTime");
            const seconds = yield this.contract.redeemEnableTime();
            return new Date(seconds.toNumber() * 1000);
        });
    }
    /**
     * Get a promise of the total reputation potentially redeemable
     */
    getReputationReward() {
        this.logContractFunctionCall("FixedReputationAllocation.reputationReward");
        return this.contract.reputationReward();
    }
    getIsEnable() {
        this.logContractFunctionCall("FixedReputationAllocation.isEnable");
        return this.contract.isEnable();
    }
    getNumberOfBeneficiaries() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.logContractFunctionCall("FixedReputationAllocation.numberOfBeneficiaries");
            const count = yield this.contract.numberOfBeneficiaries();
            return count.toNumber();
        });
    }
    /**
     * Get a promise of reputation rewardable per beneficiary
     */
    getBeneficiaryReward() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.logContractFunctionCall("FixedReputationAllocation.beneficiaryReward");
            return this.contract.beneficiaryReward();
        });
    }
    getAvatar() {
        this.logContractFunctionCall("FixedReputationAllocation.avatar");
        return this.contract.avatar();
    }
    /**
     * Get a promise of boolean indicating whether the given beneficiary has been added.
     *
     * @param beneficiaryAddress
     */
    getBeneficiaryAdded(beneficiaryAddress) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.logContractFunctionCall("FixedReputationAllocation.beneficiaries", { beneficiaryAddress });
            return this.contract.beneficiaries(beneficiaryAddress);
        });
    }
    hydrated() {
        super.hydrated();
        /* tslint:disable:max-line-length */
        this.BeneficiaryAddressAdded = this.createEventFetcherFactory(this.contract.BeneficiaryAddressAdded);
        this.Redeem = this.createEventFetcherFactory(this.contract.Redeem);
        /* tslint:enable:max-line-length */
    }
    validateEnabled(mustBeEnabled) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const enabled = yield this.getIsEnable();
            if (enabled !== mustBeEnabled) {
                throw new Error(`${mustBeEnabled} ? "The contract is not enabled" : The contract is enabled`);
            }
        });
    }
}
exports.FixedReputationAllocationWrapper = FixedReputationAllocationWrapper;
class FixedReputationAllocationType extends contractWrapperFactory_1.ContractWrapperFactory {
    deployed() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            throw new Error("FixedReputationAllocation has not been deployed");
        });
    }
}
exports.FixedReputationAllocationType = FixedReputationAllocationType;
exports.FixedReputationAllocationFactory = new FixedReputationAllocationType("FixedReputationAllocation", FixedReputationAllocationWrapper, new web3EventService_1.Web3EventService());
//# sourceMappingURL=fixedReputationAllocation.js.map