/**
 * FingerprintRotator — Browser fingerprint profiles for session diversity
 *
 * Each profile mimics a real browser user-agent + Sec-CH-UA headers.
 * Rotating through these prevents providers from associating requests
 * to a single browser identity for rate-limiting purposes.
 */

import { type Fingerprint } from "./types.ts";

// ─── Profiles ──────────────────────────────────────────────────────────────

const PROFILES: Fingerprint[] = [
  {
    id: "chrome-mac",
    userAgent:
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
    acceptLanguage: "en-US,en;q=0.9",
    secChUa: '"Not-A.Brand";v="99", "Chromium";v="135", "Google Chrome";v="135"',
    secChUaPlatform: '"macOS"',
    secChUaMobile: "?0",
  },
  {
    id: "chrome-linux",
    userAgent:
      "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
    acceptLanguage: "en-US,en;q=0.9",
    secChUa: '"Not-A.Brand";v="99", "Chromium";v="135", "Google Chrome";v="135"',
    secChUaPlatform: '"Linux"',
    secChUaMobile: "?0",
  },
  {
    id: "chrome-win",
    userAgent:
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36",
    acceptLanguage: "en-US,en;q=0.9",
    secChUa: '"Not-A.Brand";v="99", "Chromium";v="135", "Google Chrome";v="135"',
    secChUaPlatform: '"Windows"',
    secChUaMobile: "?0",
  },
  {
    id: "firefox-mac",
    userAgent:
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:148.0) Gecko/20100101 Firefox/148.0",
    acceptLanguage: "en-US,en;q=0.9",
  },
  {
    id: "firefox-linux",
    userAgent:
      "Mozilla/5.0 (X11; Linux x86_64; rv:148.0) Gecko/20100101 Firefox/148.0",
    acceptLanguage: "en-US,en;q=0.9",
  },
  {
    id: "safari-mac",
    userAgent:
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15",
    acceptLanguage: "en-US,en;q=0.9",
  },
  {
    id: "edge-mac",
    userAgent:
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0",
    acceptLanguage: "en-US,en;q=0.9",
    secChUa: '"Not-A.Brand";v="99", "Chromium";v="135", "Microsoft Edge";v="135"',
    secChUaPlatform: '"macOS"',
    secChUaMobile: "?0",
  },
  {
    id: "edge-win",
    userAgent:
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0",
    acceptLanguage: "en-US,en;q=0.9",
    secChUa: '"Not-A.Brand";v="99", "Chromium";v="135", "Microsoft Edge";v="135"',
    secChUaPlatform: '"Windows"',
    secChUaMobile: "?0",
  },
];

// ─── FingerprintRotator ────────────────────────────────────────────────────

export class FingerprintRotator {
  private index = 0;

  /** Get the next profile in round-robin order */
  next(): Fingerprint {
    const profile = PROFILES[this.index % PROFILES.length];
    this.index++;
    return profile;
  }

  /** Get a random profile */
  random(): Fingerprint {
    return PROFILES[Math.floor(Math.random() * PROFILES.length)];
  }

  /** Reset the round-robin counter */
  reset(): void {
    this.index = 0;
  }

  /** Number of available profiles */
  get count(): number {
    return PROFILES.length;
  }

  /** Build a Headers object from a fingerprint (with optional extras) */
  buildHeaders(
    fingerprint: Fingerprint,
    extra?: Record<string, string>,
  ): Record<string, string> {
    const headers: Record<string, string> = {
      "Content-Type": "application/json",
      Accept: "application/json, text/plain, */*",
      "Accept-Language": fingerprint.acceptLanguage ?? "en-US,en;q=0.9",
      "User-Agent": fingerprint.userAgent,
      ...extra,
    };
    if (fingerprint.secChUa) {
      headers["Sec-CH-UA"] = fingerprint.secChUa;
      headers["Sec-CH-UA-Mobile"] = fingerprint.secChUaMobile ?? "?0";
      headers["Sec-CH-UA-Platform"] = fingerprint.secChUaPlatform ?? '"Windows"';
    }
    return headers;
  }

  /** List all profiles */
  listAll(): Fingerprint[] {
    return [...PROFILES];
  }
}
