"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRouteUrl = exports.createRouter = exports.createRoute = exports.openapi = void 0;
const express_1 = require("express");
const yamljs_1 = __importDefault(require("yamljs"));
const path_1 = require("path");
const common_stuff_1 = require("common-stuff");
const querystring_1 = require("querystring");
exports.openapi = yamljs_1.default.load(path_1.resolve(__dirname, '../../../openapi.yaml'));
function getPathByOperation(operation) {
    const value = common_stuff_1.flatMap(Object.entries(exports.openapi.paths), ([url, data]) => {
        return common_stuff_1.flatMap(Object.entries(data), ([method, value]) => {
            if (typeof value !== 'string' && 'operationId' in value) {
                if (value.operationId === operation) {
                    return [
                        {
                            url: url,
                            method: method,
                        },
                    ];
                }
            }
            return [];
        });
    })[0];
    if (!value) {
        throw new Error(`Operation with id ${operation} not found in openapi configuration`);
    }
    return value;
}
function createRoute(operation, resolver) {
    return {
        ...getPathByOperation(operation),
        resolver,
    };
}
exports.createRoute = createRoute;
function createRouter(routes) {
    return routes.reduce((prev, cur) => {
        const url = cur.url.replace(/{([a-zA-Z]+)}/g, ':$1');
        if (cur.method === 'get') {
            return prev.get(url, cur.resolver);
        }
        if (cur.method === 'post') {
            return prev.post(url, cur.resolver);
        }
        return prev;
    }, express_1.Router());
}
exports.createRouter = createRouter;
function getRouteUrl(operation, params, query) {
    const queryString = Object.keys(query || {}).length ? `?${querystring_1.stringify(query)}` : '';
    return `${Object.entries(params || {}).reduce((prev, [key, value]) => {
        return prev.replace(`{${key}}`, encodeURIComponent(String(value)));
    }, getPathByOperation(operation).url)}${queryString}`;
}
exports.getRouteUrl = getRouteUrl;
