"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const loggingService_1 = require("./loggingService");
const absoluteVote_js_1 = require("./wrappers/absoluteVote.js");
const contributionReward_js_1 = require("./wrappers/contributionReward.js");
const daoCreator_js_1 = require("./wrappers/daoCreator.js");
const genesisProtocol_js_1 = require("./wrappers/genesisProtocol.js");
const globalConstraintRegistrar_js_1 = require("./wrappers/globalConstraintRegistrar.js");
const schemeRegistrar_js_1 = require("./wrappers/schemeRegistrar.js");
const tokenCapGC_js_1 = require("./wrappers/tokenCapGC.js");
const upgradeScheme_js_1 = require("./wrappers/upgradeScheme.js");
const vestingScheme_js_1 = require("./wrappers/vestingScheme.js");
const voteInOrganizationScheme_js_1 = require("./wrappers/voteInOrganizationScheme.js");
/**
 * Service that provides access to Arc.js contract wrapper classes and class factories.
 */
class WrapperService {
    /**
     * initialize() must be called before any of the static properties will have values.
     * It is called by ArcInitialize(), which in tur must be invoked by any application using Arc.js.
     *
     * @param options
     */
    static initialize(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            loggingService_1.LoggingService.debug("WrapperService: initializing");
            /**
             * Deployed contract wrappers by name.
             */
            const filter = (options && options.filter) ?
                Object.assign({}, WrapperService.noWrappersFilter, options.filter) :
                WrapperService.allWrappersFilter;
            /* tslint:disable:max-line-length */
            WrapperService.wrappers.AbsoluteVote = filter.AbsoluteVote ? yield absoluteVote_js_1.AbsoluteVoteFactory.deployed() : null;
            WrapperService.wrappers.ContributionReward = filter.ContributionReward ? yield contributionReward_js_1.ContributionRewardFactory.deployed() : null;
            WrapperService.wrappers.DaoCreator = filter.DaoCreator ? yield daoCreator_js_1.DaoCreatorFactory.deployed() : null;
            WrapperService.wrappers.GenesisProtocol = filter.GenesisProtocol ? yield genesisProtocol_js_1.GenesisProtocolFactory.deployed() : null;
            WrapperService.wrappers.GlobalConstraintRegistrar = filter.GlobalConstraintRegistrar ? yield globalConstraintRegistrar_js_1.GlobalConstraintRegistrarFactory.deployed() : null;
            WrapperService.wrappers.SchemeRegistrar = filter.SchemeRegistrar ? yield schemeRegistrar_js_1.SchemeRegistrarFactory.deployed() : null;
            WrapperService.wrappers.TokenCapGC = filter.TokenCapGC ? yield tokenCapGC_js_1.TokenCapGCFactory.deployed() : null;
            WrapperService.wrappers.UpgradeScheme = filter.UpgradeScheme ? yield upgradeScheme_js_1.UpgradeSchemeFactory.deployed() : null;
            WrapperService.wrappers.VestingScheme = filter.VestingScheme ? yield vestingScheme_js_1.VestingSchemeFactory.deployed() : null;
            WrapperService.wrappers.VoteInOrganizationScheme = filter.VoteInOrganizationScheme ? yield voteInOrganizationScheme_js_1.VoteInOrganizationSchemeFactory.deployed() : null;
            /* tslint:enable:max-line-length */
            /**
             * Contract wrappers grouped by type
             */
            WrapperService.wrappersByType.allWrappers = Object.values(WrapperService.wrappers);
            WrapperService.wrappersByType.globalConstraints = [
                WrapperService.wrappers.TokenCapGC,
            ];
            WrapperService.wrappersByType.other = [
                WrapperService.wrappers.DaoCreator,
            ];
            WrapperService.wrappersByType.schemes = [
                WrapperService.wrappers.ContributionReward,
                WrapperService.wrappers.GenesisProtocol,
                WrapperService.wrappers.GlobalConstraintRegistrar,
                WrapperService.wrappers.SchemeRegistrar,
                WrapperService.wrappers.UpgradeScheme,
                WrapperService.wrappers.VestingScheme,
                WrapperService.wrappers.VoteInOrganizationScheme,
            ];
            WrapperService.wrappersByType.proposalGeneratingSchemes = [
                WrapperService.wrappers.ContributionReward,
                WrapperService.wrappers.GlobalConstraintRegistrar,
                WrapperService.wrappers.SchemeRegistrar,
                WrapperService.wrappers.UpgradeScheme,
                WrapperService.wrappers.VestingScheme,
                WrapperService.wrappers.VoteInOrganizationScheme,
            ];
            WrapperService.wrappersByType.votingMachines = [
                WrapperService.wrappers.AbsoluteVote,
                WrapperService.wrappers.GenesisProtocol,
            ];
            /**
             * factories by name.  This particular way of initializing the object is due to a
             * weird thing in typedocs where it doesn't treat `factories` as a property of `WrapperService`
             * unless we initialize it this way (otherwise it shows up in the "Object Literal" section).
             */
            WrapperService.factories.AbsoluteVote = absoluteVote_js_1.AbsoluteVoteFactory;
            WrapperService.factories.ContributionReward = contributionReward_js_1.ContributionRewardFactory;
            WrapperService.factories.DaoCreator = daoCreator_js_1.DaoCreatorFactory;
            WrapperService.factories.GenesisProtocol = genesisProtocol_js_1.GenesisProtocolFactory;
            WrapperService.factories.GlobalConstraintRegistrar = globalConstraintRegistrar_js_1.GlobalConstraintRegistrarFactory;
            WrapperService.factories.SchemeRegistrar = schemeRegistrar_js_1.SchemeRegistrarFactory;
            WrapperService.factories.TokenCapGC = tokenCapGC_js_1.TokenCapGCFactory;
            WrapperService.factories.UpgradeScheme = upgradeScheme_js_1.UpgradeSchemeFactory;
            WrapperService.factories.VestingScheme = vestingScheme_js_1.VestingSchemeFactory;
            WrapperService.factories.VoteInOrganizationScheme = voteInOrganizationScheme_js_1.VoteInOrganizationSchemeFactory;
            /**
             * TODO: this should be made aware of previously-deployed GCs
             */
            /* tslint:disable-next-line:forin */
            for (const wrapperName in WrapperService.wrappers) {
                const wrapper = WrapperService.wrappers[wrapperName];
                if (wrapper) {
                    WrapperService.wrappersByAddress.set(wrapper.address, wrapper);
                }
            }
        });
    }
    /**
     * Returns the promise of an Arc.js contract wrapper or undefined if not found.
     *
     * Most useful when you have both contract name and address and wish to most
     * efficiently return the associated wrapper, or undefined when not found.
     *
     * @param contractName - name of an Arc contract, like "SchemeRegistrar"
     * @param address - optional
     */
    static getContractWrapper(contractName, address) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const factories = yield WrapperService.factories;
            const factory = factories[contractName];
            if (!factory) {
                return undefined;
            }
            if (address) {
                return factory.at(address)
                    .then((resultingContract) => resultingContract, () => undefined);
            }
            else {
                return Promise.resolve(WrapperService.wrappers[contractName]);
            }
        });
    }
}
/**
 * Wrappers by name, hydrated with contracts as deployed by the running version of Arc.js.
 */
WrapperService.wrappers = {};
/**
 * Contract wrapper factories grouped by type
 */
WrapperService.wrappersByType = {};
/**
 * Wrapper factories by name.  Use these when you want to do `.at()` or `.new()`.  You can also
 * use for `deployed()`, but the wrappers for deployed contracts are directly available from the
 * `wrappers` and `wrappersByType` properties.
 */
WrapperService.factories = {};
/**
 * Map of contract wrappers keyed by address.  For example:
 *
 * `const wrapper = WrapperService.wrappersByAddress.get(anAddress);`
 *
 * Currently only returns the wrappers for contracts that were deployed by the running
 * version of Arc.js.
 */
WrapperService.wrappersByAddress = new Map();
WrapperService.allWrappersFilter = {
    AbsoluteVote: true,
    ContributionReward: true,
    DaoCreator: true,
    GenesisProtocol: true,
    GlobalConstraintRegistrar: true,
    SchemeRegistrar: true,
    TokenCapGC: true,
    UpgradeScheme: true,
    VestingScheme: true,
    VoteInOrganizationScheme: true,
};
WrapperService.noWrappersFilter = {
    AbsoluteVote: false,
    ContributionReward: false,
    DaoCreator: false,
    GenesisProtocol: false,
    GlobalConstraintRegistrar: false,
    SchemeRegistrar: false,
    TokenCapGC: false,
    UpgradeScheme: false,
    VestingScheme: false,
    VoteInOrganizationScheme: false,
};
exports.WrapperService = WrapperService;
/**
 * for quicker access to the contract wrappers
 */
exports.ContractWrappers = WrapperService.wrappers;
/**
 * for quicker access to the contract wrapper factories
 */
exports.ContractWrapperFactories = WrapperService.factories;
/**
 * for quicker access to the contract wrapper types
 */
exports.ContractWrappersByType = WrapperService.wrappersByType;
/**
 * for quicker access to the contract wrappers by address
 */
exports.ContractWrappersByAddress = WrapperService.wrappersByAddress;
//# sourceMappingURL=wrapperService.js.map