import { Router } from "express";
import { and, count, eq, gt, inArray, isNull, sql } from "drizzle-orm";
import { heartbeatRuns, instanceUserRoles, invites } from "@zmeel/db";
import { readPersistedDevServerStatus, toDevServerHealthStatus } from "../dev-server-status.js";
import { instanceSettingsService } from "../services/instance-settings.js";
import { serverVersion } from "../version.js";
export function healthRoutes(db, opts = {
    deploymentMode: "local_trusted",
    deploymentExposure: "private",
    authReady: true,
    companyDeletionEnabled: true,
    saasMode: false,
}) {
    const router = Router();
    router.get("/", async (_req, res) => {
        if (!db) {
            res.json({ status: "ok", version: serverVersion });
            return;
        }
        try {
            await db.execute(sql `SELECT 1`);
        }
        catch {
            res.status(503).json({
                status: "unhealthy",
                version: serverVersion,
                error: "database_unreachable",
            });
            return;
        }
        let bootstrapStatus = "ready";
        let bootstrapInviteActive = false;
        if (opts.saasMode) {
            // SaaS mode: auto-provisioning handles admin creation, skip bootstrap check
            bootstrapStatus = "ready";
        }
        else if (opts.deploymentMode === "authenticated") {
            const roleCount = await db
                .select({ count: count() })
                .from(instanceUserRoles)
                .where(sql `${instanceUserRoles.role} = 'instance_admin'`)
                .then((rows) => Number(rows[0]?.count ?? 0));
            bootstrapStatus = roleCount > 0 ? "ready" : "bootstrap_pending";
            if (bootstrapStatus === "bootstrap_pending") {
                const now = new Date();
                const inviteCount = await db
                    .select({ count: count() })
                    .from(invites)
                    .where(and(eq(invites.inviteType, "bootstrap_ceo"), isNull(invites.revokedAt), isNull(invites.acceptedAt), gt(invites.expiresAt, now)))
                    .then((rows) => Number(rows[0]?.count ?? 0));
                bootstrapInviteActive = inviteCount > 0;
            }
        }
        const persistedDevServerStatus = readPersistedDevServerStatus();
        let devServer;
        if (persistedDevServerStatus) {
            const instanceSettings = instanceSettingsService(db);
            const experimentalSettings = await instanceSettings.getExperimental();
            const activeRunCount = await db
                .select({ count: count() })
                .from(heartbeatRuns)
                .where(inArray(heartbeatRuns.status, ["queued", "running"]))
                .then((rows) => Number(rows[0]?.count ?? 0));
            devServer = toDevServerHealthStatus(persistedDevServerStatus, {
                autoRestartEnabled: experimentalSettings.autoRestartDevServerWhenIdle ?? false,
                activeRunCount,
            });
        }
        res.json({
            status: "ok",
            version: serverVersion,
            deploymentMode: opts.deploymentMode,
            deploymentExposure: opts.deploymentExposure,
            authReady: opts.authReady,
            bootstrapStatus,
            bootstrapInviteActive,
            saasMode: opts.saasMode ?? false,
            features: {
                companyDeletionEnabled: opts.companyDeletionEnabled,
            },
            ...(devServer ? { devServer } : {}),
        });
    });
    return router;
}
//# sourceMappingURL=health.js.map