"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiClient = void 0;
const cactus_common_1 = require("@hyperledger/cactus-common");
const cactus_core_1 = require("@hyperledger/cactus-core");
const cactus_plugin_consortium_manual_1 = require("@hyperledger/cactus-plugin-consortium-manual");
const default_consortium_provider_1 = require("./default-consortium-provider");
const cactus_core_api_1 = require("@hyperledger/cactus-core-api");
/**
 * Class responsible for providing additional functionality to the `DefaultApi`
 * classes of the generated clients (OpenAPI generator / typescript-axios).
 *
 * Each package (plugin) can define it's own OpenAPI spec which means that they
 * all can ship with their own `DefaultApi` class that is generated directly
 * from the respective OpenAPI spec of the package/plugin.
 *
 * The functionality provided by this class is meant to be common traits that
 * can be useful for all of those different `DefaultApi` implementations.
 *
 * One such common trait is the client side component of the routing that
 * decides which Cactus node to point the `ApiClient` towards (which is in
 * itself ends up being the act of routing).
 *
 * @see https://github.com/OpenAPITools/openapi-generator/blob/v5.0.0-beta2/modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache#L337
 * @see https://github.com/OpenAPITools/openapi-generator/blob/v5.0.0/docs/generators/typescript-axios.md
 */
class ApiClient extends cactus_core_api_1.BaseAPI {
    /**
     *
     * @param ctor
     */
    extendWith(ctor) {
        const instance = new ctor(this.configuration);
        const self = this;
        cactus_common_1.Objects.getAllMethodNames(instance).forEach((method) => (self[method] = instance[method]));
        cactus_common_1.Objects.getAllFieldNames(instance).forEach((field) => (self[field] = instance[field]));
        return this;
    }
    /**
     * Builds the default `Consortium` provider that can be used by this object
     * to retrieve the Cactus Consortium metadata object when necessary (one such
     * case is when we need information about the consortium nodes to perform
     * routing requests to a specific ledger via a connector plugin, but later
     * other uses could be added as well).
     *
     * The `DefaultConsortiumProvider` class leverages the simplest consortium
     * plugin that we have at the time of this writing:
     * `@hyperledger/cactus-plugin-consortium-manual` which holds the consortium
     * metadata as pre-configured by the consortium operators.
     *
     * The pattern we use in the `ApiClient` class is that you can inject your
     * own `IAsyncProvider<Consortium>` implementation which then will be used
     * for routing information and in theory you can implement completely arbitrary
     * consortium management in your own consortium plugins which then Cactus
     * can use and leverage for the routing.
     * This allows us to support any exotic consortium management algorithms
     * that people may come up with such as storing the consortium definition in
     * a multi-sig smart contract or have the list of consortium nodes be powered
     * by some sort of automatic service discovery or anything else that people
     * might think of.
     *
     * @see {DefaultConsortiumProvider}
     */
    get defaultConsortiumDbProvider() {
        cactus_common_1.Checks.truthy(this.configuration, "ApiClient#configuration");
        const apiClient = new cactus_plugin_consortium_manual_1.DefaultApi(this.configuration);
        return new default_consortium_provider_1.DefaultConsortiumProvider({ apiClient });
    }
    /**
     * Constructs a new `ApiClient` object that is tied to whichever Cactus node
     * has a ledger connector plugin configured to talk to the distributed ledger
     * denoted by the `ledgerId` parameter of the method.
     *
     * This is part of how we do request routing between different nodes, some of
     * which may or may not run a ledger connector tied to a particular instance.
     * (E.g. this method ensures that the returned `ApiClient` instance is bound
     * to the network host of a Cactus node which does indeed have a connection
     * to the specified `ledgerId` parameter)
     *
     * @param ledgerOrId The ID of the ledger to obtain an API client object for
     * or the `Ledger` object which will be used to get the ledgerId from.
     * @param consortiumDbProvider The provider that can be used to retrieve the
     * consortium metadata at runtime for the purposes of looking up ledgers by
     * the provided `ledgerId` parameter.
     */
    async ofLedger(ledgerOrId, ctor, ctorArgs, consortiumDbProvider) {
        const fnTags = "ApiClient#forLedgerId()";
        const provider = consortiumDbProvider || this.defaultConsortiumDbProvider;
        cactus_common_1.Checks.truthy(ledgerOrId, `${fnTags}:ledgerOrId`);
        cactus_common_1.Checks.truthy(provider, `${fnTags}:consortiumDbProvider`);
        let ledgerId;
        if (typeof ledgerOrId === "string") {
            ledgerId = ledgerOrId;
        }
        else {
            ledgerId = ledgerOrId.id;
        }
        const db = await provider.get();
        const repo = new cactus_core_1.ConsortiumRepository({ db });
        const nodes = repo.nodesWithLedger(ledgerId);
        // pick a random element from the array of nodes that have a connection to
        // the target ledger (based on the ledger ID)
        const randomIdx = Math.floor(Math.random() * nodes.length);
        const randomNode = nodes[randomIdx];
        // overwrite basePath with randomNode api host
        ctorArgs.basePath = randomNode.nodeApiHost;
        // create the ApiClient configuration object
        const configuration = new cactus_core_api_1.Configuration(ctorArgs);
        return new ApiClient(configuration).extendWith(ctor);
    }
}
exports.ApiClient = ApiClient;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9tYWluL3R5cGVzY3JpcHQvYXBpLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4REFBNkU7QUFJN0UsMERBQWdFO0FBQ2hFLGtHQUEyRjtBQUMzRiwrRUFBMEU7QUFFMUUsa0VBQXNFO0FBRXRFOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQWEsU0FBVSxTQUFRLHlCQUFPO0lBQ3BDOzs7T0FHRztJQUNJLFVBQVUsQ0FDZixJQUE4QztRQUU5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUE0QixDQUFDO1FBQ3pFLE1BQU0sSUFBSSxHQUFHLElBQStCLENBQUM7UUFFN0MsdUJBQU8sQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQ3pDLENBQUMsTUFBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDdEQsQ0FBQztRQUVGLHVCQUFPLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUN4QyxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQ25ELENBQUM7UUFFRixPQUFPLElBQWdCLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F3Qkc7SUFDSCxJQUFXLDJCQUEyQjtRQUNwQyxzQkFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHlCQUF5QixDQUFDLENBQUM7UUFDN0QsTUFBTSxTQUFTLEdBQUcsSUFBSSw0Q0FBYSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN4RCxPQUFPLElBQUksdURBQXlCLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFPRDs7Ozs7Ozs7Ozs7Ozs7OztPQWdCRztJQUNJLEtBQUssQ0FBQyxRQUFRLENBQ25CLFVBQTJCLEVBQzNCLElBQThDLEVBQzlDLFFBQWlDLEVBQ2pDLG9CQUF5RDtRQUV6RCxNQUFNLE1BQU0sR0FBRyx5QkFBeUIsQ0FBQztRQUV6QyxNQUFNLFFBQVEsR0FBRyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsMkJBQTJCLENBQUM7UUFFMUUsc0JBQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLEdBQUcsTUFBTSxhQUFhLENBQUMsQ0FBQztRQUNsRCxzQkFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxNQUFNLHVCQUF1QixDQUFDLENBQUM7UUFFMUQsSUFBSSxRQUFnQixDQUFDO1FBQ3JCLElBQUksT0FBTyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLFFBQVEsR0FBRyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQzNCLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBdUIsTUFBTSxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDcEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxrQ0FBb0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFOUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUU3QywwRUFBMEU7UUFDMUUsNkNBQTZDO1FBQzdDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEMsOENBQThDO1FBQzlDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQztRQUUzQyw0Q0FBNEM7UUFDNUMsTUFBTSxhQUFhLEdBQUcsSUFBSSwrQkFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWxELE9BQU8sSUFBSSxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZELENBQUM7Q0FDRjtBQWpIRCw4QkFpSEMifQ==