import { db } from "@/db/client";
import { storageTiers } from "@/db/schema";
import { getAgentStatuses, AGENT_TIMEOUT_SECONDS } from "@/lib/agents";
import { timingSafeEqual } from "node:crypto";

export const dynamic = "force-dynamic";

// Read-only view of agent liveness, consumed by the local mount daemon
// (agent/ampelos-mountd.sh) so it can decide whether a tier's storage host is
// up. Deliberately read-only: the daemon holds the privilege, this endpoint
// never performs a mount.

function authorize(request: Request) {
  const expected = process.env.AMPELOS_AGENT_TOKEN;
  if (!expected) return { ok: false, status: 503, error: "AMPELOS_AGENT_TOKEN is not configured" };

  const header = request.headers.get("authorization") ?? "";
  const provided = header.startsWith("Bearer ") ? header.slice(7) : "";
  const a = Buffer.from(provided);
  const b = Buffer.from(expected);
  if (!provided || a.length !== b.length || !timingSafeEqual(a, b)) {
    return { ok: false, status: 401, error: "unauthorized" };
  }

  return { ok: true as const };
}

export async function GET(request: Request) {
  const auth = authorize(request);
  if (!auth.ok) return Response.json({ error: auth.error }, { status: auth.status });

  const [agents, tiers] = await Promise.all([
    getAgentStatuses(),
    db.select().from(storageTiers),
  ]);

  const agentByName = new Map(agents.map((agent) => [agent.agent, agent]));

  return Response.json({
    timeoutSeconds: AGENT_TIMEOUT_SECONDS,
    agents: agents.map((agent) => ({
      agent: agent.agent,
      online: agent.online,
      secondsSinceSeen: agent.secondsSinceSeen,
      hostname: agent.hostname,
    })),
    tiers: tiers.map((tier) => ({
      tier: tier.tier,
      basePath: tier.basePath,
      agentName: tier.agentName,
      alwaysOnline: tier.alwaysOnline,
      // null when the tier names no agent: availability is then unmanaged.
      agentOnline: tier.agentName ? Boolean(agentByName.get(tier.agentName)?.online) : null,
    })),
  });
}
