import { logger } from "./logger/index.mjs";
import { ipLimiter } from "./utils/rateLimiter.mjs";
import { aiRoute, aiRouter } from "./routes/ai.routes.mjs";
import { connectDB } from "./utils/mongoDB/connectDB.mjs";
import { bitbucketRoute, bitbucketRouter } from "./routes/bitbucket.routes.mjs";
import { dictionaryRoute, dictionaryRouter } from "./routes/dictionary.routes.mjs";
import { githubRoute, githubRouter } from "./routes/github.routes.mjs";
import { gitlabRoute, gitlabRouter } from "./routes/gitlab.routes.mjs";
import { newsletterRoute, newsletterRouter } from "./routes/newsletter.routes.mjs";
import { organizationRoute, organizationRouter } from "./routes/organization.routes.mjs";
import { projectRoute, projectRouter } from "./routes/project.routes.mjs";
import { userRoute, userRouter } from "./routes/user.routes.mjs";
import { getAuth } from "./utils/auth/getAuth.mjs";
import { getOAuth2AccessToken } from "./controllers/oAuth2.controller.mjs";
import { attachOAuthInstance, oAuth2Middleware } from "./middlewares/oAuth2.middleware.mjs";
import { authMiddleware } from "./middlewares/sessionAuth.middleware.mjs";
import { eventListenerRoute, eventListenerRouter } from "./routes/eventListener.routes.mjs";
import { searchRoute, searchRouter } from "./routes/search.routes.mjs";
import { stripeRoute, stripeRouter } from "./routes/stripe.routes.mjs";
import { tagRoute, tagRouter } from "./routes/tags.routes.mjs";
import { corsOptions } from "./utils/cors.mjs";
import { stripeWebhook } from "./webhooks/stripe.webhook.mjs";
import { intlayer, t } from "fastify-intlayer";
import fastifyRateLimit from "@fastify/rate-limit";
import fastifyCompress from "@fastify/compress";
import fastifyCookie from "@fastify/cookie";
import fastifyCors from "@fastify/cors";
import fastifyFormbody from "@fastify/formbody";
import fastifyHelmet from "@fastify/helmet";
import dotenv from "dotenv";
import Fastify from "fastify";

//#region src/index.ts
const startServer = async () => {
	const app = Fastify({
		disableRequestLogging: true,
		trustProxy: true,
		routerOptions: { ignoreTrailingSlash: true }
	});
	const env = "development";
	logger.info(`run as ${env}`);
	dotenv.config({ path: [
		`.env.${env}.local`,
		`.env.${env}`,
		".env.local",
		".env"
	] });
	await app.register(fastifyHelmet, {
		contentSecurityPolicy: false,
		global: true
	});
	await app.register(fastifyCors, corsOptions);
	await app.register(fastifyCompress);
	await app.register(fastifyCookie);
	await app.register(fastifyFormbody);
	await app.register(intlayer);
	await app.register(fastifyRateLimit, ipLimiter);
	const dbClient = await connectDB();
	await app.register(async (stripeScope) => {
		stripeScope.addContentTypeParser("application/json", { parseAs: "buffer" }, (_req, body, done) => {
			done(null, body);
		});
		stripeScope.post("/webhook/stripe", async (request, reply) => {
			const rawBody = request.body;
			await stripeWebhook({
				...request.raw,
				body: rawBody,
				headers: request.headers
			}, reply);
		});
	});
	app.get("/", async (_request, reply) => {
		return reply.send(t({
			en: "Ok - locale: en",
			fr: "Ok - locale: fr",
			es: "Ok - locale: es"
		}));
	});
	const auth = getAuth(dbClient);
	app.route({
		method: ["GET", "POST"],
		url: "/api/auth/*",
		async handler(request, reply) {
			try {
				const protocol = request.protocol;
				const host = request.headers.host;
				const url = new URL(request.url, `${protocol}://${host}`);
				const headers = new Headers();
				Object.entries(request.headers).forEach(([key, value]) => {
					if (value) headers.append(key, String(value));
				});
				const req = new Request(url.toString(), {
					method: request.method,
					headers,
					...request.body ? { body: JSON.stringify(request.body) } : {}
				});
				const response = await auth.handler(req);
				reply.status(response.status);
				response.headers.forEach((value, key) => {
					reply.header(key, value);
				});
				const responseBody = response.body ? await response.text() : null;
				return reply.send(responseBody);
			} catch (error) {
				logger.error("Authentication Error:", error);
				return reply.status(500).send({
					error: "Internal authentication error",
					code: "AUTH_FAILURE"
				});
			}
		}
	});
	app.addHook("onRequest", authMiddleware(auth));
	app.addHook("onRequest", attachOAuthInstance);
	app.post("/oauth2/token", getOAuth2AccessToken);
	app.addHook("preHandler", oAuth2Middleware);
	if (env === "development") app.addHook("onRequest", async (request) => {
		const queryDetails = {
			params: request.params,
			query: request.query,
			body: request.body,
			locals: request.locals
		};
		logger.info(`API Request - ${request.method} - ${request.url} - ${JSON.stringify(queryDetails, null, 2)}`);
	});
	await app.register(userRouter, { prefix: userRoute });
	await app.register(organizationRouter, { prefix: organizationRoute });
	await app.register(projectRouter, { prefix: projectRoute });
	await app.register(tagRouter, { prefix: tagRoute });
	await app.register(dictionaryRouter, { prefix: dictionaryRoute });
	await app.register(stripeRouter, { prefix: stripeRoute });
	await app.register(aiRouter, { prefix: aiRoute });
	await app.register(eventListenerRouter, { prefix: eventListenerRoute });
	await app.register(searchRouter, { prefix: searchRoute });
	await app.register(newsletterRouter, { prefix: newsletterRoute });
	await app.register(githubRouter, { prefix: githubRoute });
	await app.register(gitlabRouter, { prefix: gitlabRoute });
	await app.register(bitbucketRouter, { prefix: bitbucketRoute });
	await app.listen({
		port: Number(process.env.PORT) || 3100,
		host: "0.0.0.0"
	});
	logger.info(`Listening on port ${process.env.PORT || 3100}`);
};
startServer();

//#endregion
//# sourceMappingURL=index.mjs.map