/**
 * 制御盤向けのルート（`app/api/ds-agent/**`）の先頭で必ず呼ぶ認証（指示書AY 段階5-5。D5・D19）。
 *
 * proxy の `authenticateAgent()` が既に通しているが、★ルートでも Bearer を再検証して serial を得る★
 * （proxy から後段へ serial をヘッダで渡さない。ヘッダは詐称できるため。D5）。
 * 通ったら relay の `touch()` で最終接続日時と版を更新する（★すべての制御盤のリクエストで。表5 R7・D19・指示書BJ J9★）。
 */
import { NextResponse } from "next/server";
import { getRelay } from "@/lib/ds-agent/relay";
import { verifyAgentAuthorization } from "@/lib/ds-agent/tokens";
import type { ApiError } from "@/lib/types";

export type RequireAgentResult = { ok: true; serial: string } | { ok: false; response: Response };

/** 合わなければ `null`（拒否しない）。接続の記録に使う（指示書BJ J9） */
const AGENT_VERSION = /^[0-9A-Za-z.+-]{1,32}$/;

export function agentVersionOf(request: Request): string | null {
  const raw = request.headers.get("x-agent-version");
  return raw !== null && AGENT_VERSION.test(raw) ? raw : null;
}

export async function requireAgent(request: Request): Promise<RequireAgentResult> {
  const serial = await verifyAgentAuthorization(request.headers.get("authorization"));
  if (serial === null) {
    const body: ApiError = { error: { code: "unauthorized", message: "認証が必要です", details: null } };
    return { ok: false, response: NextResponse.json(body, { status: 401 }) };
  }
  getRelay().touch(serial, agentVersionOf(request));
  return { ok: true, serial };
}
