"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/**
 * A single instance of ProposalService provides services relating to a single
 * type of proposal (TProposal), for example a proposal to contribute rewards to a beneficiary.
 * When constructing a ProposalService we pass to the constructor a `ProposalMaker<TProposal, TEventArgs>`
 * that provides functions enabling ProposalService to do its job with respect to the given TProposal.
 * Note it is not scoped to a particular Avatar.
 */
class ProposalService {
    constructor(web3EventService) {
        this.web3EventService = web3EventService;
    }
    /**
     * Returns an EntityFetcherFactory for fetching proposal-related events.  Can take any EventFetcherFactory
     * whose event args supply `_proposalId`.  Returns events as a promise of `TProposal`.  You must supply an
     * `EventFetcherFactory` for fetching the events and a callback to transform `TEventArgs` to a promise of `TProposal`.
     * Each entity, when the associated proposal is votable and options.votingMachine is supplied,
     * will also contain a `votingMachine` property of type `IntVoteInterfaceWrapper`.
     * @type TEventArgs The type of the `args` object in the event.
     * @type TProposal The type of object returned as a transformation of the `args` information in each event.
     * @param options
     */
    getProposalEvents(options) {
        if (!options.transformEventCallback) {
            throw new Error("transformEventCallback must be supplied");
        }
        if (!options.proposalsEventFetcher) {
            throw new Error("proposalsEventFetcher must be supplied");
        }
        const votableOnly = !!options.votableOnly;
        if (votableOnly && !options.votingMachine) {
            throw new Error("votingMachine must be supplied when votableOnly is true");
        }
        return this.web3EventService.createEntityFetcherFactory(options.proposalsEventFetcher, (event) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            let entity;
            if (options.votingMachine) {
                const isVotable = yield options.votingMachine.isVotable({ proposalId: event.args._proposalId });
                entity = yield (((!votableOnly || isVotable) ?
                    options.transformEventCallback(event) :
                    Promise.resolve(undefined)));
                if (entity && isVotable) {
                    entity.votingMachine = options.votingMachine;
                }
            }
            else {
                entity = yield options.transformEventCallback(event);
            }
            return entity;
        }), options.baseArgFilter);
    }
    /**
     * Returns promise of an EntityFetcherFactory for fetching votable proposals from the
     * given `IntVoteInterfaceWrapper`. The proposals are returned as promises of instances
     * of `VotableProposal`.
     *
     * @param votingMachineAddress
     */
    getVotableProposals(votingMachine) {
        return this.web3EventService.createEntityFetcherFactory(votingMachine.VotableProposals, (event) => {
            return Promise.resolve({
                avatarAddress: event.args._avatar,
                numOfChoices: event.args._numOfChoices.toNumber(),
                paramsHash: event.args._paramsHash,
                proposalId: event.args._proposalId,
                proposerAddress: event.args._proposer,
            });
        });
    }
    /**
     * Returns promise of an EntityFetcherFactory for fetching executed proposals from the
     * given `IntVoteInterfaceWrapper`.
     * The proposals are returned as promises of instances of `ExecutedProposal`.
     *
     * @param votingMachineAddress
     */
    getExecutedProposals(votingMachine) {
        return this.web3EventService.createEntityFetcherFactory(votingMachine.ExecuteProposal, (event) => {
            return Promise.resolve({
                decision: event.args._decision.toNumber(),
                proposalId: event.args._proposalId,
                totalReputation: event.args._totalReputation,
            });
        });
    }
}
exports.ProposalService = ProposalService;
//# sourceMappingURL=proposalService.js.map