// 認証: パスワード照合 + HMAC署名セッション（依存ゼロ / Web Crypto）
import { hmacSign, timingSafeEqual } from "./util.js";

export const SESSION_COOKIE = "mds_session";
const DEFAULT_TTL_MS = 1000 * 60 * 60 * 24 * 7; // 7日

/** パスワード照合（定数時間） */
export function checkPassword(input: string, expected: string): boolean {
  if (!expected) return false;
  return timingSafeEqual(input, expected);
}

/** セッショントークン生成: base64url(exp).署名 */
export async function createSession(
  secret: string,
  now: number,
  ttlMs = DEFAULT_TTL_MS,
): Promise<string> {
  const exp = now + ttlMs;
  const payload = btoa(JSON.stringify({ exp }))
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "");
  const sig = await hmacSign(secret, payload);
  return `${payload}.${sig}`;
}

/** セッション検証: 署名一致 & 未失効 */
export async function verifySession(
  secret: string,
  token: string | undefined,
  now: number,
): Promise<boolean> {
  if (!token || !token.includes(".")) return false;
  const [payload, sig] = token.split(".");
  if (!payload || !sig) return false;
  const expected = await hmacSign(secret, payload);
  if (!timingSafeEqual(sig, expected)) return false;
  try {
    const b64 = payload.replace(/-/g, "+").replace(/_/g, "/");
    const json = JSON.parse(atob(b64)) as { exp: number };
    return typeof json.exp === "number" && json.exp > now;
  } catch {
    return false;
  }
}

export function sessionCookie(token: string, ttlMs = DEFAULT_TTL_MS): string {
  const maxAge = Math.floor(ttlMs / 1000);
  return `${SESSION_COOKIE}=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=${maxAge}`;
}

export function clearCookie(): string {
  return `${SESSION_COOKIE}=; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=0`;
}

export function readCookie(header: string | null, name: string): string | undefined {
  if (!header) return undefined;
  for (const part of header.split(";")) {
    const [k, ...v] = part.trim().split("=");
    if (k === name) return v.join("=");
  }
  return undefined;
}
