import 'server-only'
import { timingSafeEqual } from 'node:crypto'

/**
 * The Mac agent authenticates with static bearer tokens, never a session
 * cookie. Same shape as steward's agent-auth: a read token for fetching work,
 * and a separate callback secret as a second factor for writing results back.
 *
 * This is single-user infrastructure behind a domain only this family uses, but
 * the endpoints carry children's schoolwork and can write to the measurement
 * record, so both are required in production.
 */

function safeEqual(got: string, want: string): boolean {
  const a = Buffer.from(got)
  const b = Buffer.from(want)
  if (a.length !== b.length) return false
  return timingSafeEqual(a, b)
}

/** Read access: fetching work payloads and handwriting images. */
export function checkAgentAuth(req: Request): boolean {
  const expected = process.env.AGENT_TOKEN
  if (!expected) return false
  const m = (req.headers.get('authorization') || '').match(/^Bearer\s+(.+)$/i)
  if (!m) return false
  return safeEqual(m[1], expected)
}

/** Write access: posting scores, items, feedback and status back. */
export function checkCallbackSecret(req: Request): boolean {
  const expected = process.env.AGENT_CALLBACK_SECRET
  if (!expected) return false
  return safeEqual(req.headers.get('x-callback-secret') || '', expected)
}

/** Both, for anything that mutates the measurement record. */
export function checkAgentWrite(req: Request): boolean {
  return checkAgentAuth(req) && checkCallbackSecret(req)
}
