import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
import consola from "consola";
import fs from "fs";
import "reflect-metadata";
import { createExpressServer, getMetadataArgsStorage } from "routing-controllers";
import { routingControllersToSpec } from 'routing-controllers-openapi';
import { config } from '../src/config';
import authchecker from "../src/middlewares/authchecker";
import { ErrorHandler } from '../src/middlewares/ErrorHandler';

const CONTROLLERS_FILE_EXTENSION = process.env.NODE_ENV === 'production' ? 'js' : 'ts';
createExpressServer({
    authorizationChecker: authchecker,
    middlewares: [ErrorHandler],
    development: config.development,
    cors: true,
    routePrefix: "/api",
    controllers: [`${__dirname}/controllers/*.${CONTROLLERS_FILE_EXTENSION}`],
});

const storage = getMetadataArgsStorage();
const schemas = validationMetadatasToSchemas({
    refPointerPrefix: "#/components/schemas/",
});

//Spec creation based on the previously created schemas
const spec = routingControllersToSpec(
    storage,
    {
        routePrefix: "/api"
    },
    {
        components: {
            schemas,
            "securitySchemes": {
                "AuthToken": {
                    "type": "http",
                    "scheme": "bearer",
                    "bearerFormat": "JWT",
                    description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
                },
                "RefreshTokenCookie": {
                    "type": "apiKey",
                    "in": "cookie",
                    "name": "lfk_backend__refresh_token",
                    description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
                },
                "StatsApiToken": {
                    "type": "http",
                    "scheme": "bearer",
                    description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients)."
                }
            }
        },
        info: {
            description: "The the backend API for the LfK! runner system.",
            title: "LfK! Backend API",
            version: "0.0.5",
        },
    }
);

try {
    fs.writeFileSync("./openapi.json", JSON.stringify(spec), { encoding: "utf-8" });
    consola.success("Exported openapi spec to openapi.json");
} catch (error) {
    consola.error("Couldn't export the openapi spec");
}
