"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTestScenarioArtifacts = getTestScenarioArtifacts;
const openapi_1 = require("@samchon/openapi");
const getTestTemplateCode_1 = require("./getTestTemplateCode");
function getTestScenarioArtifacts(ctx, scenario) {
    return __awaiter(this, void 0, void 0, function* () {
        const compiler = yield ctx.compiler();
        const document = filterDocument(scenario, ctx.state().interface.document);
        const entries = Object.entries(yield compiler.interface.write(document));
        const filter = (prefix, exclude) => {
            const result = entries.filter(([key]) => key.startsWith(prefix) === true);
            return Object.fromEntries(exclude
                ? result.filter(([key]) => key.startsWith(exclude) === false)
                : result);
        };
        return {
            document,
            sdk: filter("src/api", "src/api/structures"),
            dto: filter("src/api/structures"),
            e2e: filter("test/features"),
            template: (0, getTestTemplateCode_1.getTestTemplateCode)(scenario, document),
        };
    });
}
function filterDocument(scenario, document) {
    const operations = document.operations.filter((op) => (scenario.endpoint.method === op.method &&
        scenario.endpoint.path === op.path) ||
        scenario.dependencies.some((dp) => dp.endpoint.method === op.method && dp.endpoint.path === op.path));
    const components = {
        authorization: document.components.authorization,
        schemas: {},
    };
    const visit = (typeName) => {
        openapi_1.OpenApiTypeChecker.visit({
            components: document.components,
            schema: { $ref: `#/components/schemas/${typeName}` },
            closure: (s) => {
                if (openapi_1.OpenApiTypeChecker.isReference(s)) {
                    const key = s.$ref.split("/").pop();
                    components.schemas[key] = document.components.schemas[key];
                }
            },
        });
    };
    for (const op of operations) {
        if (op.requestBody)
            visit(op.requestBody.typeName);
        if (op.responseBody)
            visit(op.responseBody.typeName);
    }
    return {
        operations,
        components,
    };
}
//# sourceMappingURL=getTestScenarioArtifacts.js.map