import { env } from "./env.js";
import { getLogger as getLogger$1 } from "./logger.js";
import { flushBatchProcessor } from "./instrumentation.js";
import { evalRoutes } from "./domains/evals/index.js";
import { workflowRoutes } from "./domains/evals/workflow/routes.js";
import { authCorsConfig, defaultCorsConfig, playgroundCorsConfig, runCorsConfig, signozCorsConfig, workAppsCorsConfig } from "./middleware/cors.js";
import { errorHandler } from "./middleware/errorHandler.js";
import { sessionContext } from "./middleware/sessionAuth.js";
import { manageBearerOrSessionAuth } from "./middleware/manageAuth.js";
import { runApiKeyAuth, runApiKeyAuthExcept } from "./middleware/runAuth.js";
import { requireTenantAccess } from "./middleware/tenantAccess.js";
import { workAppsAuth } from "./middleware/workAppsAuth.js";
import "./middleware/index.js";
import { manageRoutes } from "./domains/manage/index.js";
import mcp_default from "./domains/mcp/routes/mcp.js";
import { runRoutes } from "./domains/run/index.js";
import { workAppsRoutes } from "./domains/work-apps/index.js";
import { branchScopedDbMiddleware } from "./middleware/branchScopedDb.js";
import { projectConfigMiddleware, projectConfigMiddlewareExcept } from "./middleware/projectConfig.js";
import { manageRefMiddleware, runRefMiddleware, writeProtectionMiddleware } from "./middleware/ref.js";
import { executionBaggageMiddleware } from "./middleware/tracing.js";
import { setupOpenAPIRoutes } from "./openapi.js";
import { cleanupStreamChunksHandler } from "./routes/cleanupStreamChunks.js";
import { healthChecksHandler } from "./routes/healthChecks.js";
import { restartWorkflowHandler } from "./routes/restartScheduler.js";
import { OpenAPIHono } from "@hono/zod-openapi";
import { getInProcessFetch, getWaitUntil, registerAppFetch } from "@inkeep/agents-core";
import { githubRoutes } from "@inkeep/agents-work-apps/github";
import { Hono } from "hono";
import { cors } from "hono/cors";
import { requestId } from "hono/request-id";
import { pinoLogger } from "hono-pino";

//#region src/createApp.ts
const logger = getLogger$1("agents-api");
const isWebhookRoute = (path) => {
	return path.includes("/triggers/") && !path.endsWith("/triggers") && !path.endsWith("/triggers/");
};
function createAgentsHono(config) {
	const { serverConfig, credentialStores, auth, sandboxConfig } = config;
	const app = new OpenAPIHono();
	app.use("*", requestId());
	app.use("*", async (c, next) => {
		await next();
		c.header("X-Content-Type-Options", "nosniff");
		c.header("Referrer-Policy", "strict-origin-when-cross-origin");
		c.header("X-XSS-Protection", "0");
	});
	app.use("/api/auth/*", cors(authCorsConfig));
	if (auth) {
		if (env.ENVIRONMENT === "development") app.post("/api/auth/dev-session", async (c) => {
			const bypassSecret = env.INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET;
			const authHeader = c.req.header("Authorization");
			if (!bypassSecret || authHeader !== `Bearer ${bypassSecret}`) return c.json({ error: "Unauthorized" }, 401);
			const email = env.INKEEP_AGENTS_MANAGE_UI_USERNAME;
			if (!email) return c.json({ error: "Dev credentials not configured. Run pnpm db:auth:init first." }, 400);
			const ctx = await auth.$context;
			const found = await ctx.internalAdapter.findUserByEmail(email);
			if (!found) return c.json({ error: "Dev user not found. Run pnpm db:auth:init first." }, 400);
			const session = await ctx.internalAdapter.createSession(found.user.id);
			const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(ctx.secret), {
				name: "HMAC",
				hash: "SHA-256"
			}, false, ["sign"]);
			const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(session.token));
			const base64Sig = btoa(String.fromCharCode(...new Uint8Array(sig)));
			const encodedValue = encodeURIComponent(`${session.token}.${base64Sig}`);
			const { name: cookieName, attributes } = ctx.authCookies.sessionToken;
			const { path, httpOnly, secure, sameSite = "lax" } = attributes;
			const maxAge = ctx.sessionConfig.expiresIn;
			const sameSiteValue = sameSite.charAt(0).toUpperCase() + sameSite.slice(1);
			const cookieString = `${cookieName}=${encodedValue}; Path=${path}; Max-Age=${maxAge}${httpOnly ? "; HttpOnly" : ""}${secure ? "; Secure" : ""}; SameSite=${sameSiteValue}`;
			c.header("set-cookie", cookieString);
			return c.json({ ok: true });
		});
		app.on(["POST", "GET"], "/api/auth/*", (c) => {
			return auth.handler(c.req.raw);
		});
	}
	app.use("/run/*", cors(runCorsConfig));
	app.use("/manage/tenants/*/playground/token", cors(playgroundCorsConfig));
	app.use("/manage/tenants/*/signoz/*", cors(signozCorsConfig));
	app.use("/work-apps/*", cors(workAppsCorsConfig));
	app.use("*", async (c, next) => {
		if (c.req.path.startsWith("/api/auth/")) return next();
		if (c.req.path.startsWith("/run/")) return next();
		if (c.req.path.startsWith("/work-apps/")) return next();
		if (c.req.path.includes("/playground/token")) return next();
		if (c.req.path.includes("/signoz/")) return next();
		if (c.req.path.includes("/work-apps/github/")) return next();
		return cors(defaultCorsConfig)(c, next);
	});
	app.use("*", async (c, next) => {
		c.set("serverConfig", serverConfig);
		c.set("credentialStores", credentialStores);
		c.set("auth", auth);
		if (sandboxConfig) c.set("sandboxConfig", sandboxConfig);
		await next();
	});
	app.use("/run/*", async (c, next) => {
		if (c.req.header("content-type")?.includes("application/json")) try {
			const body = await c.req.json();
			c.set("requestBody", body);
		} catch (error) {
			logger.debug({ error }, "Failed to parse JSON body, continuing without parsed body");
		}
		return next();
	});
	app.use(pinoLogger({
		pino: getLogger$1("agents-api").getPinoInstance(),
		http: { onResLevel(c) {
			if (c.res.status === 503 && c.req.path.startsWith("/.well-known/workflow/")) return "info";
			if (c.res.status >= 500) return "error";
			if (c.req.path.includes("/signoz/")) return "debug";
			return "info";
		} }
	}));
	app.onError(errorHandler);
	app.use("*", sessionContext());
	app.route("/", healthChecksHandler);
	app.route("/", restartWorkflowHandler);
	app.route("/", cleanupStreamChunksHandler);
	app.use("/manage/tenants/*", manageBearerOrSessionAuth());
	app.use("/manage/tenants/:tenantId/*", requireTenantAccess());
	app.use("*", async (_c, next) => {
		await next();
		const waitUntil = await getWaitUntil();
		if (waitUntil) waitUntil(flushBatchProcessor());
	});
	app.use("/run/tenants/*", runApiKeyAuthExcept(isWebhookRoute));
	app.use("/run/agents/*", runApiKeyAuth());
	app.use("/run/v1/*", runApiKeyAuth());
	app.use("/run/api/*", runApiKeyAuth());
	app.use("/manage/tenants/*", async (c, next) => manageRefMiddleware(c, next));
	app.use("/manage/tenants/*", (c, next) => writeProtectionMiddleware(c, next));
	app.use("/manage/tenants/*", async (c, next) => branchScopedDbMiddleware(c, next));
	app.use("/run/*", async (c, next) => {
		if (c.req.path.startsWith("/run/auth/")) return next();
		return runRefMiddleware(c, next);
	});
	const isLightweightRunRoute = (path) => path.startsWith("/run/v1/conversations") || path.startsWith("/run/v1/feedback");
	app.use("/run/tenants/*", projectConfigMiddlewareExcept(isWebhookRoute));
	app.use("/run/agents/*", projectConfigMiddleware);
	app.use("/run/v1/*", projectConfigMiddlewareExcept(isLightweightRunRoute));
	app.use("/run/api/*", projectConfigMiddleware);
	app.use("/run/*", async (c, next) => {
		return executionBaggageMiddleware()(c, next);
	});
	app.route("/manage", manageRoutes);
	app.route("/run", runRoutes);
	app.route("/.well-known", workflowRoutes);
	app.post("/index", async (c) => {
		const originalUrl = new URL(c.req.url);
		const bodyBuffer = await c.req.arrayBuffer();
		const targetUrl = new URL("/.well-known/workflow/v1/flow", originalUrl.origin);
		const forwardedRequest = new Request(targetUrl.toString(), {
			method: "POST",
			headers: new Headers(c.req.raw.headers),
			body: bodyBuffer
		});
		return getInProcessFetch()(forwardedRequest);
	});
	app.route("/evals", evalRoutes);
	app.route("/work-apps/github", githubRoutes);
	app.use("/work-apps/slack/workspaces/*", workAppsAuth);
	app.use("/work-apps/slack/users/*", workAppsAuth);
	app.route("/work-apps", workAppsRoutes);
	app.route("/mcp", mcp_default);
	setupOpenAPIRoutes(app);
	const base = new Hono();
	base.route("/", app);
	registerAppFetch(base.request.bind(base));
	return base;
}

//#endregion
export { createAgentsHono, isWebhookRoute };