"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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __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 logger_1 = __importDefault(require("./logger"));
const node_fetch_1 = __importDefault(require("node-fetch"));
const helpers_1 = require("./helpers");
const https = __importStar(require("https"));
const http = __importStar(require("http"));
const getAgent = (url) => {
    return url.startsWith("https")
        ? new https.Agent({
            rejectUnauthorized: false,
        })
        : new http.Agent();
};
const eaApi = async (eaApiUrl, token) => {
    const agent = getAgent(eaApiUrl);
    return {
        runEntity: async ({ type, id, configuration }, onDispatch) => {
            const variables = [];
            let systemDefinitionName;
            let virtualUserName;
            configuration?.values.forEach((variable) => {
                if (variable.name === "System Definition") {
                    systemDefinitionName = variable.value;
                }
                else if (variable.name === "Virtual User") {
                    virtualUserName = variable.value;
                }
                else {
                    variables.push(variable);
                }
            });
            return new Promise(async (resolve, reject) => {
                let location = null;
                let retryAfter;
                logger_1.default.info(`Running entity [${type} ${id}] on ${eaApiUrl}`);
                // First, we need to dispatch the execution to the background
                try {
                    const requestUrl = `${eaApiUrl}api/background/executeAsync?type=${type}&id=${id}`;
                    logger_1.default.info(`Requesting ${requestUrl}`);
                    const response = await (0, node_fetch_1.default)(requestUrl, {
                        method: "POST",
                        headers: {
                            authorization: token,
                            "Content-Type": "application/json",
                        },
                        agent,
                        body: JSON.stringify({
                            configuration: {
                                systemDefinitionName,
                                virtualUserName,
                                variables: variables.length > 0 ? variables : undefined,
                            },
                        }),
                    });
                    location = response.headers.get("location");
                    retryAfter = parseInt(response.headers.get("retry-after") || "10", 10);
                    await (0, helpers_1.wait)(retryAfter * 1000);
                }
                catch (error) {
                    reject(error);
                }
                if (!location) {
                    reject(new Error(`${eaApiUrl} has not responded with location to fetch the execution results from.`));
                }
                // Poll for the results until the execution is finished
                while (location) {
                    try {
                        const response = await (0, node_fetch_1.default)(location, {
                            method: "GET",
                            headers: {
                                authorization: token,
                            },
                            agent,
                        });
                        if (response.status === 202) {
                            if (onDispatch) {
                                await onDispatch();
                            }
                            const retryAfter = response.headers.get("retry-after") || "10";
                            location = response.headers.get("location");
                            logger_1.default.info(`Waiting for the results. Will retry after ${retryAfter} seconds`);
                            await (0, helpers_1.wait)(parseInt(retryAfter, 10) * 1000);
                        }
                        else {
                            const result = await response.json();
                            resolve(result);
                            break;
                        }
                    }
                    catch (error) {
                        reject(error);
                        break;
                    }
                }
            });
        },
        getScriptTestCaseMapping: async (testCases = []) => {
            return new Promise(async (resolve, reject) => {
                let response;
                try {
                    response = await (0, node_fetch_1.default)(`${eaApiUrl}api/background/testCaseMap`, {
                        method: "POST",
                        headers: {
                            authorization: token,
                            "Content-Type": "application/json",
                        },
                        body: JSON.stringify(testCases.map((id) => Number.parseInt(id, 10))),
                        agent,
                    });
                }
                catch (error) {
                    reject(error);
                }
                if (response && response.ok) {
                    resolve(response.json());
                }
                else {
                    reject(new Error("No response"));
                }
            });
        },
    };
};
exports.default = eaApi;
//# sourceMappingURL=eaApi.js.map