import { ResponseStatus } from '@adonisjs/core/http';
import _ from 'lodash';
import { AKVineHandlerMetaData } from '../../crud/vine_handler_metadata.js';
import { HandlerGetOptions } from '../openapi_router_macros.js';
import { VineParser } from '../service/vine_parser.js';
export class HandlerParser {
    #handler;
    constructor(handler) {
        this.#handler = handler;
    }
    parse() {
        const handlerOptions = HandlerGetOptions(this.#handler);
        const requestSchema = this.parseSchema('request');
        const responseStatusCode = AKVineHandlerMetaData.getResponseStatusCode(this.#handler) || ResponseStatus.Ok;
        const responseSchema = this.parseSchema('response');
        return {
            summary: handlerOptions.name || _.startCase(_(this.#handler.name).split('.').last()),
            description: handlerOptions.description,
            security: [
                {
                    BearerAuth: [],
                },
                {
                    QueryTokenAuth: [],
                },
            ],
            parameters: this.parseQueryParameters(),
            requestBody: _.isEmpty(requestSchema.schema)
                ? undefined
                : {
                    required: true,
                    content: {
                        'application/json': requestSchema,
                    },
                },
            responses: {
                [responseStatusCode]: {
                    description: this.statusCodeToHumanReadable(responseStatusCode),
                    content: {
                        'application/json': responseSchema,
                    },
                },
                ...this.parseReponseErrors(),
            },
        };
    }
    parseQueryParameters() {
        const requestQueryParameters = AKVineHandlerMetaData.getRequestQueryParameters(this.#handler);
        if (requestQueryParameters)
            return new VineParser(requestQueryParameters.validator).parseAsParameter();
    }
    parseSchema(type) {
        const { validator } = (type === 'request'
            ? AKVineHandlerMetaData.getRequestSchema(this.#handler)
            : AKVineHandlerMetaData.getResponseSchema(this.#handler)) || {};
        const openApiSchema = validator ? new VineParser(validator).parseAsSchema().schema : undefined;
        return {
            schema: openApiSchema,
        };
    }
    parseReponseErrors() {
        const responseErrors = AKVineHandlerMetaData.getResponseErrors(this.#handler) || [];
        return _(responseErrors)
            .groupBy((e) => e.status.toString())
            .mapValues((exceptions) => ({
            description: 'Exception(s) possible(s)',
            content: {
                'application/json': {
                    schema: exceptions.length > 1
                        ? {
                            oneOf: _.map(exceptions, this.parseApiException),
                        }
                        : this.parseApiException(exceptions[0]),
                },
            },
        }))
            .value();
    }
    parseApiException(apiException) {
        return {
            type: 'object',
            properties: {
                code: {
                    type: 'string',
                    enum: [apiException.code],
                },
                message: {
                    type: 'string',
                    enum: [apiException.message],
                },
            },
        };
    }
    statusCodeToHumanReadable(statusCode) {
        for (const [key, value] of Object.entries(ResponseStatus)) {
            if (value === statusCode)
                return _.startCase(key);
        }
    }
}
//# sourceMappingURL=handler_parser.js.map