"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const Rule_1 = require("./Rule");
const TagsRule_1 = require("./TagsRule");
const AuthorsRule_1 = require("./AuthorsRule");
const WeightRule_1 = require("./WeightRule");
const CustomRPCRule_1 = require("./CustomRPCRule");
const ValidationException_1 = require("../validation/ValidationException");
const VotingPowerRule_1 = require("./VotingPowerRule");
const WeightForPeriodRule_1 = require("./WeightForPeriodRule");
const VotesCountRule_1 = require("./VotesCountRule");
const AgeOfPostRule_1 = require("./AgeOfPostRule");
const FirstPostRule_1 = require("./FirstPostRule");
const PayoutRule_1 = require("./PayoutRule");
const VotersRule_1 = require("./VotersRule");
const ExpirationDateRule_1 = require("./ExpirationDateRule");
/**
 * This is a rule prototyper. Prototyping is done when rules are loaded from json file.
 */
class RulePrototyper {
    /**
     * Prototypes and validates a ruleset. This function converts a plain json rules (without methods) to
     * proper Rule objects that implements all needed methods. It also validates each rule object (checks if
     * it contains all required parameters).
     * @param unprototypedRuleset - ruleset to prototype
     */
    static prototypeRuleset(unprototypedRuleset) {
        const out = {
            name: unprototypedRuleset.name,
            rules: unprototypedRuleset.rules.map(rule => RulePrototyper.fromUnprototypedRule(rule))
        };
        return out;
    }
    static fromUnprototypedRule(unprototyped) {
        /* if rule implements validate, it means that it already had prototype */
        if (unprototyped.validate)
            return unprototyped;
        /* otherwise we have to append a prototype */
        else if (unprototyped.rule === Rule_1.Rule.Type.Tags) {
            return RulePrototyper.prototypeRule(new TagsRule_1.TagsRule(TagsRule_1.TagsRule.Mode.ALLOW, []), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.Authors) {
            return RulePrototyper.prototypeRule(new AuthorsRule_1.AuthorsRule(AuthorsRule_1.AuthorsRule.Mode.ALLOW, []), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.Weight) {
            return RulePrototyper.prototypeRule(new WeightRule_1.WeightRule(0, 0), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.VotingPower) {
            return RulePrototyper.prototypeRule(new VotingPowerRule_1.VotingPowerRule(VotingPowerRule_1.VotingPowerRule.Mode.MORE_THAN, 0), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.WeightForPeriod) {
            return RulePrototyper.prototypeRule(new WeightForPeriodRule_1.WeightForPeriodRule(0, WeightForPeriodRule_1.WeightForPeriodRule.PeriodUnit.SECOND, 0), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.CustomRPC) {
            return RulePrototyper.prototypeRule(new CustomRPCRule_1.CustomRPCRule("", 0, "", ""), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.AgeOfPost) {
            return RulePrototyper.prototypeRule(new AgeOfPostRule_1.AgeOfPostRule(AgeOfPostRule_1.AgeOfPostRule.Mode.OLDER_THAN, 0, AgeOfPostRule_1.AgeOfPostRule.TimeUnit.SECOND), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.FirstPost) {
            return RulePrototyper.prototypeRule(new FirstPostRule_1.FirstPostRule(), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.Payout) {
            return RulePrototyper.prototypeRule(new PayoutRule_1.PayoutRule(PayoutRule_1.PayoutRule.Mode.EQUAL, 0), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.VotesCount) {
            return RulePrototyper.prototypeRule(new VotesCountRule_1.VotesCountRule(VotesCountRule_1.VotesCountRule.Mode.MORE_THAN, 0), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.Voters) {
            return RulePrototyper.prototypeRule(new VotersRule_1.VotersRule(VotersRule_1.VotersRule.Mode.NONE, []), unprototyped);
        }
        else if (unprototyped.rule === Rule_1.Rule.Type.ExpirationDate) {
            return RulePrototyper.prototypeRule(new ExpirationDateRule_1.ExpirationDateRule(new Date().toISOString()), unprototyped);
        }
        else
            throw new ValidationException_1.ValidationException("There is no rule with this type (rule=" + unprototyped.rule + ")");
    }
    static prototypeRule(prototyperRule, unprototypedObj) {
        prototyperRule.validateRuleObject(unprototypedObj);
        return _.merge(prototyperRule, prototyperRule, unprototypedObj);
    }
}
exports.RulePrototyper = RulePrototyper;
//# sourceMappingURL=RulePrototyper.js.map