"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 _ = require("lodash");
const Rule_1 = require("./Rule");
const ValidationException_1 = require("../validation/ValidationException");
class VotingPowerRule extends Rule_1.Rule {
    constructor(mode, value) {
        super();
        this.rule = Rule_1.Rule.Type.VotingPower;
        this.mode = mode;
        this.value = value;
    }
    type() {
        return Rule_1.Rule.Type.VotingPower;
    }
    validate(voteorder, context) {
        return __awaiter(this, void 0, void 0, function* () {
            this.validateRuleObject(this);
            const delegatorAccount = yield context.getAccountInfo(context.getDelegatorUsername());
            if (!delegatorAccount)
                throw new Error("Delegator account info is undefined");
            if (this.mode == VotingPowerRule.Mode.EQUAL) {
                if (delegatorAccount.voting_power !== this.value)
                    throw new ValidationException_1.ValidationException("Delegator voting power (" + this.votingpowerToPercent(delegatorAccount.voting_power) + ") does not equal "
                        + this.votingpowerToPercent(this.value));
            }
            else if (this.mode == VotingPowerRule.Mode.MORE_THAN) {
                if (delegatorAccount.voting_power <= this.value)
                    throw new ValidationException_1.ValidationException("Delegator voting power (" + this.votingpowerToPercent(delegatorAccount.voting_power) + ") is not more than "
                        + this.votingpowerToPercent(this.value));
            }
            else if (this.mode == VotingPowerRule.Mode.LESS_THAN) {
                if (delegatorAccount.voting_power >= this.value)
                    throw new ValidationException_1.ValidationException("Delegator voting power (" + this.votingpowerToPercent(delegatorAccount.voting_power) + ") is not less than "
                        + this.votingpowerToPercent(this.value));
            }
            else {
                throw new Error("Unknown mode of voting power rule: " + this.mode);
            }
        });
    }
    validateRuleObject(unprototypedObj) {
        ["value", "mode"].forEach(prop => {
            if (!_.has(unprototypedObj, prop))
                throw new ValidationException_1.ValidationException("VotingPowerRule: property " + prop + " is missing");
        });
        if (!_.includes([VotingPowerRule.Mode.MORE_THAN, VotingPowerRule.Mode.LESS_THAN, VotingPowerRule.Mode.EQUAL], unprototypedObj.mode))
            throw new ValidationException_1.ValidationException("VotingPowerRule: unknown mode " + unprototypedObj.mode);
    }
    getDescription() {
        let out = "The delegator has ";
        switch (this.mode) {
            case VotingPowerRule.Mode.MORE_THAN:
                out += "more than";
                break;
            case VotingPowerRule.Mode.LESS_THAN:
                out += "less than";
                break;
            case VotingPowerRule.Mode.EQUAL:
                out += "exactly";
                break;
            default: out += this.mode;
        }
        out += " " + this.votingpowerToPercent(this.value) + " voting power";
        return out;
    }
    votingpowerToPercent(vp) {
        return (vp / 100).toFixed(2) + "%";
    }
}
exports.VotingPowerRule = VotingPowerRule;
(function (VotingPowerRule) {
    let Mode;
    (function (Mode) {
        Mode["MORE_THAN"] = "more_than";
        Mode["LESS_THAN"] = "less_than";
        Mode["EQUAL"] = "equal";
    })(Mode = VotingPowerRule.Mode || (VotingPowerRule.Mode = {}));
})(VotingPowerRule = exports.VotingPowerRule || (exports.VotingPowerRule = {}));
//# sourceMappingURL=VotingPowerRule.js.map