import { timingSafeEqual } from 'crypto'
import { NextRequest, NextResponse } from 'next/server'
import { recordSecurityEvent } from './security-observability'

function safeTokenEquals(left: string, right: string): boolean {
  const leftBuffer = Buffer.from(left)
  const rightBuffer = Buffer.from(right)

  if (leftBuffer.length !== rightBuffer.length) {
    return false
  }

  return timingSafeEqual(leftBuffer, rightBuffer)
}

/**
 * Enforces authorization for cron endpoints.
 * Returns a response when auth fails, otherwise null.
 */
export function requireCronAuth(request: NextRequest, endpoint = 'unknown'): NextResponse | null {
  const secret = process.env.CRON_SECRET?.trim()

  // Fail closed when secret is missing.
  if (!secret) {
    recordSecurityEvent('cron_secret_missing', {
      endpoint,
      reason: 'CRON_SECRET is not configured',
    }, 'error')
    return NextResponse.json({ error: 'Service unavailable' }, { status: 503 })
  }

  const authorization = request.headers.get('authorization')
  if (!authorization?.startsWith('Bearer ')) {
    recordSecurityEvent('cron_auth_rejected', {
      endpoint,
      reason: 'Missing or invalid Authorization header',
    })
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  const token = authorization.slice('Bearer '.length).trim()
  if (!token || !safeTokenEquals(token, secret)) {
    recordSecurityEvent('cron_auth_rejected', {
      endpoint,
      reason: 'Bearer token mismatch',
    })
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  return null
}
