"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonSchemaNamingConvention = void 0;
const utils_1 = require("@autobe/utils");
const openapi_1 = require("@samchon/openapi");
var JsonSchemaNamingConvention;
(function (JsonSchemaNamingConvention) {
    JsonSchemaNamingConvention.operations = (operations) => {
        const typeNames = new Set();
        operate(typeNames, operations);
    };
    JsonSchemaNamingConvention.schemas = (operations, ...componentSchemas) => {
        const typeNames = new Set();
        for (const schemas of componentSchemas)
            for (const key of Object.keys(schemas))
                typeNames.add(key);
        const answer = operate(typeNames, operations);
        for (const dict of componentSchemas)
            for (const x of Object.keys(dict)) {
                const y = answer(x);
                if (x === y)
                    continue;
                dict[y] = dict[x];
                delete dict[x];
            }
        for (const dict of componentSchemas)
            for (const x of Object.values(dict)) {
                openapi_1.OpenApiTypeChecker.visit({
                    components: { schemas: dict },
                    schema: x,
                    closure: (s) => {
                        if (openapi_1.OpenApiTypeChecker.isReference(s) === false)
                            return;
                        s.$ref = `#/components/schemas/${answer(s.$ref.split("/").pop())}`;
                    },
                });
            }
    };
    const operate = (typeNames, operations) => {
        for (const op of operations) {
            if (op.requestBody)
                typeNames.add(op.requestBody.typeName);
            if (op.responseBody)
                typeNames.add(op.responseBody.typeName);
        }
        const answer = prepare(typeNames);
        for (const op of operations) {
            if (op.requestBody)
                op.requestBody.typeName = answer(op.requestBody.typeName);
            if (op.responseBody)
                op.responseBody.typeName = answer(op.responseBody.typeName);
        }
        return answer;
    };
    const prepare = (typeNames) => {
        const similar = new Map();
        const getKey = (v) => v.split(".")[0].toLowerCase();
        const getValue = (v) => v.split(".")[0];
        const emplace = (v) => utils_1.MapUtil.take(similar, getKey(v), () => []).push(getValue(v));
        for (const v of typeNames)
            emplace(v);
        const solution = new Map();
        for (const [key, values] of similar) {
            if (values.length === 1)
                continue;
            const winner = values.sort((a, b) => countCapitalLetters(b) - countCapitalLetters(a))[0];
            solution.set(key, winner);
        }
        return (v) => {
            const key = getKey(v);
            if (solution.has(key) === false)
                return v;
            return [solution.get(key), ...v.split(".").slice(1)].join(".");
        };
    };
})(JsonSchemaNamingConvention || (exports.JsonSchemaNamingConvention = JsonSchemaNamingConvention = {}));
const countCapitalLetters = (str) => (str.match(/[A-Z]/g) || []).length;
//# sourceMappingURL=JsonSchemaNamingConvention.js.map