"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 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.
     */
    static initialize() {
        return __awaiter(this, void 0, void 0, function* () {
            loggingService_1.LoggingService.debug("WrapperService: initializing");
            /**
             * Deployed contract wrappers by name.
             */
            WrapperService.wrappers.AbsoluteVote = yield absoluteVote_js_1.AbsoluteVoteFactory.deployed();
            WrapperService.wrappers.ContributionReward = yield contributionreward_js_1.ContributionRewardFactory.deployed();
            WrapperService.wrappers.DaoCreator = yield daocreator_js_1.DaoCreatorFactory.deployed();
            WrapperService.wrappers.GenesisProtocol = yield genesisProtocol_js_1.GenesisProtocolFactory.deployed();
            WrapperService.wrappers.GlobalConstraintRegistrar = yield globalconstraintregistrar_js_1.GlobalConstraintRegistrarFactory.deployed();
            WrapperService.wrappers.SchemeRegistrar = yield schemeregistrar_js_1.SchemeRegistrarFactory.deployed();
            WrapperService.wrappers.TokenCapGC = yield tokenCapGC_js_1.TokenCapGCFactory.deployed();
            WrapperService.wrappers.UpgradeScheme = yield upgradescheme_js_1.UpgradeSchemeFactory.deployed();
            WrapperService.wrappers.VestingScheme = yield vestingscheme_js_1.VestingSchemeFactory.deployed();
            WrapperService.wrappers.VoteInOrganizationScheme = yield voteInOrganizationScheme_js_1.VoteInOrganizationSchemeFactory.deployed();
            /**
             * 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.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];
                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 __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();
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