"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createServer = void 0;
const fastify_1 = __importDefault(require("fastify"));
const owl_1 = __importDefault(require("./owl"));
const redis_1 = __importDefault(require("./redis"));
const tokens_1 = __importDefault(require("./routes/tokens"));
const tokens_2 = __importDefault(require("./tokens"));
const health_1 = __importDefault(require("./routes/health"));
const queues_1 = __importDefault(require("./routes/queues"));
const usage_1 = __importDefault(require("./routes/usage"));
const swagger_1 = __importDefault(require("@fastify/swagger"));
const swagger_ui_1 = __importDefault(require("@fastify/swagger-ui"));
const package_json_1 = __importDefault(require("../../../package.json"));
const basic_auth_1 = __importDefault(require("./basic-auth"));
const token_auth_1 = __importDefault(require("./token-auth"));
const activity_1 = __importDefault(require("./routes/activity"));
const fastify_blipp_1 = __importDefault(require("fastify-blipp"));
const cors_1 = __importDefault(require("@fastify/cors"));
const telemetry_1 = __importDefault(require("./telemetry"));
const sentry_1 = __importDefault(require("./sentry"));
const logger_1 = __importDefault(require("./logger"));
const index_1 = __importDefault(require("./routes/index"));
const structured_logger_1 = require("../shared/structured-logger");
const jobs_repo_1 = require("./jobs-repo");
const rate_limit_1 = __importDefault(require("@fastify/rate-limit"));
const posthog_1 = __importDefault(require("./posthog"));
async function createServer({ port = 9181, host = "0.0.0.0", runningInDocker = false, redisFactory, passphrases, disableTelemetry, logger, jwtPublicKey, rateLimiter, postHogApiKey, }) {
    var _a;
    const app = (0, fastify_1.default)({
        logger: logger instanceof structured_logger_1.StructuredLogger ? logger.log : undefined,
        maxParamLength: 500,
    });
    if (!disableTelemetry) {
        app.register(sentry_1.default);
    }
    if (postHogApiKey) {
        app.register(posthog_1.default, {
            apiKey: postHogApiKey,
        });
    }
    app.register(rate_limit_1.default, {
        enableDraftSpec: true,
        max: (_a = rateLimiter === null || rateLimiter === void 0 ? void 0 : rateLimiter.max) !== null && _a !== void 0 ? _a : 10000,
        keyGenerator: (req) => { var _a; return (_a = req.headers.authorization) !== null && _a !== void 0 ? _a : req.ip; },
    });
    app.register(fastify_blipp_1.default);
    app.register(cors_1.default, {
        origin: "*",
    });
    const enableAdminBasedAuth = !!(passphrases === null || passphrases === void 0 ? void 0 : passphrases.length);
    app.decorate("adminBasedAuthEnabled", enableAdminBasedAuth);
    app.register(swagger_1.default, {
        openapi: {
            info: {
                title: "Quirrel API",
                description: "The Queueing Solution for Serverless.",
                version: package_json_1.default.version,
                contact: {
                    email: "info@quirrel.dev",
                    name: "Quirrel",
                    url: "https://quirrel.dev",
                },
                license: {
                    name: "MIT License",
                    url: "https://github.com/quirrel-dev/quirrel/blob/main/LICENSE",
                },
            },
            externalDocs: {
                url: "https://docs.quirrel.dev",
                description: "Find general documentation here",
            },
            components: {
                securitySchemes: {
                    Token: enableAdminBasedAuth || jwtPublicKey
                        ? {
                            type: "http",
                            scheme: "bearer",
                            description: `Main auth scheme. Tokens can be issued via ${enableAdminBasedAuth
                                ? jwtPublicKey
                                    ? "JWT / Admin"
                                    : "Admin"
                                : "JWT"}.`,
                        }
                        : undefined,
                    Admin: enableAdminBasedAuth
                        ? {
                            type: "http",
                            scheme: "basic",
                            description: "Used for admin tasks like issuing new tokens. Username is ignored, password is specified via environment variables.",
                        }
                        : undefined,
                    Impersonation: enableAdminBasedAuth
                        ? {
                            type: "http",
                            scheme: "basic",
                            description: "Username must be the token ID to be impersonated, password is admin password.",
                        }
                        : undefined,
                },
            },
            tags: [
                {
                    name: "Queueing",
                },
                {
                    name: "DX",
                },
                {
                    name: "Admin",
                },
            ],
        },
    });
    app.register(swagger_ui_1.default, {
        routePrefix: "/documentation",
    });
    app.register(logger_1.default, {
        logger,
    });
    app.register(redis_1.default, { redisFactory });
    app.register(owl_1.default);
    app.register(token_auth_1.default, {
        enable: enableAdminBasedAuth,
        passphrases: passphrases !== null && passphrases !== void 0 ? passphrases : [],
        jwtPublicKey,
    });
    app.register(jobs_repo_1.jobsRepoPlugin);
    if (!disableTelemetry) {
        app.register(telemetry_1.default, { runningInDocker });
    }
    if (passphrases) {
        app.register(basic_auth_1.default, { passphrases });
        app.register(usage_1.default, { prefix: "/usage" });
        if (!jwtPublicKey) {
            app.register(tokens_2.default);
            app.register(tokens_1.default, { prefix: "/tokens" });
        }
    }
    app.register(health_1.default, { prefix: "/health" });
    app.register(queues_1.default, { prefix: "/queues" });
    app.register(activity_1.default, { prefix: "/activity" });
    app.register(index_1.default);
    app.ready(async () => {
        var _a, _b, _c;
        const debug = false;
        if (debug) {
            app.blipp();
        }
        app.swagger();
        (_a = app.telemetrist) === null || _a === void 0 ? void 0 : _a.dispatch("ready");
        if (passphrases) {
            (_b = app.telemetrist) === null || _b === void 0 ? void 0 : _b.dispatch("auth enabled");
        }
        if (port !== 9181) {
            (_c = app.telemetrist) === null || _c === void 0 ? void 0 : _c.dispatch("custom port");
        }
    });
    await app.listen({
        port,
        host,
    });
    const { address, port: runningPort } = app.server.address();
    logger === null || logger === void 0 ? void 0 : logger.started(`${address}:${runningPort}`, !disableTelemetry);
    return {
        server: app.server,
        app,
        port,
        async close() {
            app.log.info("Closing.");
            await app.close();
        },
    };
}
exports.createServer = createServer;
//# sourceMappingURL=index.js.map