"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const os_1 = require("os");
const Benchmark = __importStar(require("benchmark"));
const uuid_1 = require("uuid");
const jose_1 = require("jose");
const run_time_error_cjs_1 = require("run-time-error-cjs");
const grpc = __importStar(require("@grpc/grpc-js"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const cactus_core_1 = require("@hyperledger/cactus-core");
const cactus_core_api_1 = require("@hyperledger/cactus-core-api");
const public_api_1 = require("../../../main/typescript/public-api");
const public_api_2 = require("../../../main/typescript/public-api");
const LOG_TAG = "[packages/cactus-cmd-api-server/src/test/typescript/benchmark/run-cmd-api-server-benchmark.ts]";
const createTestInfrastructure = async (opts) => {
    const logLevel = opts.logLevel || "DEBUG";
    const jwtKeyPair = await (0, jose_1.generateKeyPair)("RS256", { modulusLength: 4096 });
    const jwtPublicKey = await (0, jose_1.exportSPKI)(jwtKeyPair.publicKey);
    const expressJwtOptions = {
        algorithms: ["RS256"],
        secret: jwtPublicKey,
        audience: (0, uuid_1.v4)(),
        issuer: (0, uuid_1.v4)(),
    };
    const socketIoJwtOptions = {
        secret: jwtPublicKey,
        algorithms: ["RS256"],
    };
    const authorizationConfig = {
        unprotectedEndpointExemptions: [],
        expressJwtOptions,
        socketIoJwtOptions,
        socketIoPath: cactus_core_api_1.Constants.SocketIoConnectionPathV1,
    };
    const pluginsPath = path_1.default.join(__dirname, "../../../../../../", // walk back up to the project root
    "packages/cactus-cmd-api-server/src/test/typescript/benchmark/run-cmd-api-server-benchmark/", // the dir path from the root
    (0, uuid_1.v4)());
    const pluginManagerOptionsJson = JSON.stringify({ pluginsPath });
    const pluginRegistry = new cactus_core_1.PluginRegistry({ logLevel });
    const configService = new public_api_1.ConfigService();
    const apiSrvOpts = await configService.newExampleConfig();
    apiSrvOpts.logLevel = logLevel;
    apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson;
    apiSrvOpts.authorizationProtocol = public_api_1.AuthorizationProtocol.JSON_WEB_TOKEN;
    apiSrvOpts.authorizationConfigJson = authorizationConfig;
    apiSrvOpts.configFile = "";
    apiSrvOpts.apiCorsDomainCsv = "*";
    apiSrvOpts.apiPort = 0;
    apiSrvOpts.cockpitPort = 0;
    apiSrvOpts.grpcPort = 0;
    apiSrvOpts.crpcPort = 0;
    apiSrvOpts.apiTlsEnabled = false;
    apiSrvOpts.grpcMtlsEnabled = false;
    apiSrvOpts.plugins = [];
    const config = await configService.newExampleConfigConvict(apiSrvOpts);
    const apiServer = new public_api_1.ApiServer({
        config: config.getProperties(),
        pluginRegistry,
    });
    apiServer.initPluginRegistry({ pluginRegistry });
    const startResponsePromise = apiServer.start();
    const { addressInfoApi, addressInfoGrpc } = await startResponsePromise;
    const protocol = apiSrvOpts.apiTlsEnabled ? "https" : "http";
    const { address, port } = addressInfoApi;
    const apiHost = `${protocol}://${address}:${port}`;
    const grpcHost = `${addressInfoGrpc.address}:${addressInfoGrpc.port}`;
    const jwtPayload = { name: "Peter", location: "Albertirsa" };
    const validJwt = await new jose_1.SignJWT(jwtPayload)
        .setProtectedHeader({ alg: "RS256" })
        .setIssuer(expressJwtOptions.issuer)
        .setAudience(expressJwtOptions.audience)
        .sign(jwtKeyPair.privateKey);
    const validBearerToken = `Bearer ${validJwt}`;
    const apiClient = new public_api_1.ApiServerApiClient(new public_api_1.ApiServerApiClientConfiguration({
        basePath: apiHost,
        baseOptions: { headers: { Authorization: validBearerToken } },
        logLevel,
    }));
    const grpcCredentials = grpc.credentials.createInsecure();
    return {
        grpcCredentials,
        httpApi: apiClient,
        grpcHost,
        apiServer,
    };
};
const main = async (opts) => {
    const logLevel = "WARN";
    const gitRootPath = path_1.default.join(__dirname, "../../../../../../");
    console.log("%s gitRootPath=%s", LOG_TAG, gitRootPath);
    const DEFAULT_OUTPUT_FILE_RELATIVE_PATH = ".tmp/benchmark-results/cmd-api-server/run-cmd-api-server-benchmark.ts.log";
    const relativeOutputFilePath = opts.argv[2] === undefined
        ? DEFAULT_OUTPUT_FILE_RELATIVE_PATH
        : opts.argv[2];
    console.log("%s DEFAULT_OUTPUT_FILE_RELATIVE_PATH=%s", LOG_TAG, DEFAULT_OUTPUT_FILE_RELATIVE_PATH);
    console.log("%s opts.argv[2]=%s", LOG_TAG, opts.argv[2]);
    console.log("%s relativeOutputFilePath=%s", LOG_TAG, relativeOutputFilePath);
    const absoluteOutputFilePath = path_1.default.join(gitRootPath, relativeOutputFilePath);
    console.log("%s absoluteOutputFilePath=%s", LOG_TAG, absoluteOutputFilePath);
    const absoluteOutputDirPath = path_1.default.dirname(absoluteOutputFilePath);
    console.log("%s absoluteOutputDirPath=%s", LOG_TAG, absoluteOutputDirPath);
    await fs_extra_1.default.mkdirp(absoluteOutputDirPath);
    console.log("%s mkdir -p OK: %s", LOG_TAG, absoluteOutputDirPath);
    const { apiServer, httpApi, grpcHost, grpcCredentials } = await createTestInfrastructure({ logLevel });
    const minSamples = 100;
    const suite = new Benchmark.Suite({});
    const cycles = [];
    await new Promise((resolve, reject) => {
        suite
            .add("cmd-api-server_HTTP_GET_getOpenApiSpecV1", {
            defer: true,
            minSamples,
            fn: async function (deferred) {
                await httpApi.getOpenApiSpecV1();
                deferred.resolve();
            },
        })
            .add("cmd-api-server_gRPC_GetOpenApiSpecV1", {
            defer: true,
            minSamples,
            fn: async function (deferred) {
                const grpcClient = new public_api_2.default_service.org.hyperledger.cactus.cmd_api_server.DefaultServiceClient(grpcHost, grpcCredentials);
                await new Promise((resolve, reject) => {
                    const req = new public_api_2.empty.google.protobuf.Empty();
                    grpcClient.GetOpenApiSpecV1(req, (err3, value) => {
                        if (err3) {
                            reject(err3);
                        }
                        else if (value) {
                            resolve(value);
                        }
                        else {
                            reject(new run_time_error_cjs_1.RuntimeError("Response object received is falsy."));
                        }
                    });
                });
                grpcClient.close();
                deferred.resolve();
            },
        })
            .on("cycle", (event) => {
            // Output benchmark result by converting benchmark result to string
            // Example line on stdout:
            // cmd-api-server_HTTP_GET_getOpenApiSpecV1 x 1,020 ops/sec ±2.25% (177 runs sampled)
            const cycle = String(event.target);
            console.log("%s Benchmark.js CYCLE: %s", LOG_TAG, cycle);
            cycles.push(cycle);
        })
            .on("complete", function () {
            console.log("%s Benchmark.js COMPLETE.", LOG_TAG);
            resolve(suite);
        })
            .on("error", (ex) => {
            console.log("%s Benchmark.js ERROR: %o", LOG_TAG, ex);
            reject(ex);
        })
            .run();
    });
    const data = cycles.join(os_1.EOL);
    console.log("%s Writing results...", LOG_TAG);
    await fs_extra_1.default.writeFile(absoluteOutputFilePath, data, { encoding: "utf-8" });
    console.log("%s Wrote results to %s", LOG_TAG, absoluteOutputFilePath);
    await apiServer.shutdown();
    console.log("%s Shut down API server OK", LOG_TAG);
};
main({ argv: process.argv }).catch((ex) => {
    console.error("%s process crashed with:", LOG_TAG, ex);
    process.exit(1);
});
//# sourceMappingURL=data:application/json;base64, 