// OAuth 探索文件（RFC 9728 Protected Resource Metadata、RFC 8414 Authorization Server Metadata）
// 以「當前請求的 origin」動態組出——同一份碼在 mcp.arcrun.dev 與 arcrun-mcp.<sub>.workers.dev 都正確。

/** 從請求 URL 取 origin（scheme://host），canonical 用小寫 scheme/host。 */
export function originOf(reqUrl: string): string {
  const u = new URL(reqUrl);
  return `${u.protocol.toLowerCase()}//${u.host.toLowerCase()}`;
}

/** 本 MCP server 的 canonical resource URI（RFC 8707 audience）——MCP 端點在 /mcp。 */
export function resourceUri(origin: string): string {
  return `${origin}/mcp`;
}

/**
 * 把 client 傳的 `resource`（RFC 8707）正規化成 canonical 形式，好和 `resourceUri(origin)` 嚴格比對。
 * 正規化規則與 originOf/resourceUri 產出的 canonical 一致：
 *   - scheme + host 小寫（URL 也自動去掉預設 port，如 https 的 :443）
 *   - path 去尾斜線（`/mcp/` → `/mcp`；根 `/` 保留）
 *   - 丟棄 query / fragment（resource 不該帶）
 * 非法 URL → null。
 */
export function normalizeResource(value: string): string | null {
  let u: URL;
  try {
    u = new URL(value);
  } catch {
    return null;
  }
  const scheme = u.protocol.toLowerCase(); // 含結尾冒號，如 "https:"
  const host = u.host.toLowerCase(); // 含非預設 port；預設 port 已被 URL 去掉
  let path = u.pathname;
  if (path.length > 1 && path.endsWith("/")) path = path.slice(0, -1);
  return `${scheme}//${host}${path}`;
}

/**
 * 判斷 client 傳的 `resource` 正規化後是否 == 本 server 的 canonical resource URI。
 * 用於 /authorize、/token 的簽發端把關（fail fast），避免尾斜線/大小寫變體造成
 * 「OAuth 成功但每次打 /mcp 都 401 aud mismatch」的最難 debug 劇本。
 */
export function resourceMatches(resourceParam: string, origin: string): boolean {
  const n = normalizeResource(resourceParam);
  return n !== null && n === resourceUri(origin);
}

/** RFC 9728 Protected Resource Metadata。 */
export function protectedResourceMetadata(origin: string) {
  return {
    resource: resourceUri(origin),
    authorization_servers: [origin],
    scopes_supported: ["mcp"],
    bearer_methods_supported: ["header"],
  };
}

/** RFC 8414 Authorization Server Metadata（本 worker 同時是 AS）。 */
export function authorizationServerMetadata(origin: string) {
  return {
    issuer: origin,
    authorization_endpoint: `${origin}/authorize`,
    token_endpoint: `${origin}/token`,
    registration_endpoint: `${origin}/register`,
    response_types_supported: ["code"],
    grant_types_supported: ["authorization_code"],
    code_challenge_methods_supported: ["S256"],
    token_endpoint_auth_methods_supported: ["none"], // public client + PKCE
    scopes_supported: ["mcp"],
  };
}

/**
 * RFC 9728 §5.1 WWW-Authenticate 回應標頭——401 時指向 protected-resource metadata，
 * claude.ai 靠這個發現 OAuth authorization server。
 */
export function wwwAuthenticateHeader(origin: string, error?: string): string {
  const metaUrl = `${origin}/.well-known/oauth-protected-resource`;
  let h = `Bearer resource_metadata="${metaUrl}"`;
  if (error) h += `, error="${error}"`;
  return h;
}
