"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const commonTypes_1 = require("../commonTypes");
const contractWrapperBase_1 = require("../contractWrapperBase");
const contractWrapperFactory_1 = require("../contractWrapperFactory");
class SchemeRegistrarWrapper extends contractWrapperBase_1.ContractWrapperBase {
    constructor() {
        super(...arguments);
        this.name = "SchemeRegistrar";
        this.friendlyName = "Scheme Registrar";
        this.factory = exports.SchemeRegistrarFactory;
        /**
         * Events
         */
        /* tslint:disable:max-line-length */
        this.NewSchemeProposal = this.createEventFetcherFactory("NewSchemeProposal");
        this.RemoveSchemeProposal = this.createEventFetcherFactory("RemoveSchemeProposal");
        this.ProposalExecuted = this.createEventFetcherFactory("ProposalExecuted");
        this.ProposalDeleted = this.createEventFetcherFactory("ProposalDeleted");
    }
    /* tslint:enable:max-line-length */
    /**
     * Note relating to permissions: According rules defined in the Controller,
     * this SchemeRegistrar is only capable of registering schemes that have
     * either no permissions or have the permission to register other schemes.
     * Therefore Arc's SchemeRegistrar is not capable of registering schemes
     * that have permissions greater than its own, thus excluding schemes having
     * the permission to add/remove global constraints or upgrade the controller.
     * The Controller will throw an exception when an attempt is made
     * to add or remove schemes having greater permissions than the scheme attempting the change.
     */
    proposeToAddModifyScheme(options = {}) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const defaults = {
                permissions: null,
                schemeName: null,
            };
            options = Object.assign({}, defaults, options);
            if (!options.avatar) {
                throw new Error("avatar is not defined");
            }
            if (!options.schemeAddress) {
                throw new Error("schemeAddress is not defined");
            }
            if (!options.schemeParametersHash) {
                throw new Error("schemeParametersHash is not defined");
            }
            /**
             * throws an Error if not valid, yields 0 if null or undefined
             */
            let permissions;
            if (options.schemeName) {
                /**
                 * then we are adding/removing an Arc scheme and can get and check its permissions.
                 */
                permissions = options.permissions || commonTypes_1.DefaultSchemePermissions[options.schemeName];
                if (permissions > this.getDefaultPermissions()) {
                    throw new Error("SchemeRegistrar cannot work with schemes having greater permissions than its own");
                }
            }
            else {
                permissions = options.permissions;
                if (!permissions) {
                    throw new Error("permissions is not defined; it is required for non-Arc schemes (where schemeName is undefined)");
                }
            }
            this.logContractFunctionCall("SchemeRegistrar.proposeScheme", options);
            const txResult = yield this.wrapTransactionInvocation("SchemeRegistrar.proposeToAddModifyScheme", options, () => {
                return this.contract.proposeScheme(options.avatar, options.schemeAddress, options.schemeParametersHash, commonTypes_1.SchemePermissions.toString(permissions));
            });
            return new contractWrapperBase_1.ArcTransactionProposalResult(txResult.tx);
        });
    }
    proposeToRemoveScheme(options = {}) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.avatar) {
                throw new Error("avatar is not defined");
            }
            if (!options.schemeAddress) {
                throw new Error("schemeAddress address is not defined");
            }
            this.logContractFunctionCall("SchemeRegistrar.proposeToRemoveScheme", options);
            const txResult = yield this.wrapTransactionInvocation("SchemeRegistrar.proposeToRemoveScheme", options, () => {
                return this.contract.proposeToRemoveScheme(options.avatar, options.schemeAddress);
            });
            return new contractWrapperBase_1.ArcTransactionProposalResult(txResult.tx);
        });
    }
    setParameters(params) {
        const _super = name => super[name];
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.validateStandardSchemeParams(params);
            return _super("_setParameters").call(this, "SchemeRegistrar.setParameters", params.voteParametersHash, params.voteRemoveParametersHash ? params.voteRemoveParametersHash : params.voteParametersHash, params.votingMachineAddress);
        });
    }
    getDefaultPermissions() {
        return commonTypes_1.DefaultSchemePermissions.SchemeRegistrar;
    }
    getSchemePermissions(avatarAddress) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return this._getSchemePermissions(avatarAddress);
        });
    }
    getSchemeParameters(avatarAddress) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return this._getSchemeParameters(avatarAddress);
        });
    }
    getParameters(paramsHash) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const params = yield this.getParametersArray(paramsHash);
            return {
                voteParametersHash: params[0],
                voteRemoveParametersHash: params[1],
                votingMachineAddress: params[2],
            };
        });
    }
}
exports.SchemeRegistrarWrapper = SchemeRegistrarWrapper;
exports.SchemeRegistrarFactory = new contractWrapperFactory_1.ContractWrapperFactory("SchemeRegistrar", SchemeRegistrarWrapper);
//# sourceMappingURL=schemeRegistrar.js.map