#!/usr/bin/env python3
"""
Download Google Fonts woff2 files (latin subset only) for self-hosting.

Fonts downloaded:
  - Source Serif 4: 400, 600, 400-italic
  - Inter: 400, 500, 600, 700
  - JetBrains Mono: 400

Files are saved to src/fonts/ with naming: {family}-{weight}{-italic}.woff2
"""

import os
import re
import urllib.request

# Chrome User-Agent to get woff2 format from Google Fonts CSS API
USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/120.0.0.0 Safari/537.36"
)

# Google Fonts CSS2 API URLs
FONT_REQUESTS = [
    # Source Serif 4: 400 normal, 600 normal, 400 italic
    (
        "https://fonts.googleapis.com/css2?"
        "family=Source+Serif+4:ital,wght@0,400;0,600;1,400"
        "&display=swap"
    ),
    # Inter: 400, 500, 600, 700
    (
        "https://fonts.googleapis.com/css2?"
        "family=Inter:wght@400;500;600;700"
        "&display=swap"
    ),
    # JetBrains Mono: 400
    (
        "https://fonts.googleapis.com/css2?"
        "family=JetBrains+Mono:wght@400"
        "&display=swap"
    ),
]

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)
FONTS_DIR = os.path.join(PROJECT_ROOT, "src", "fonts")


def fetch_css(url):
    """Fetch CSS from Google Fonts with Chrome User-Agent to get woff2."""
    req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT})
    with urllib.request.urlopen(req) as resp:
        return resp.read().decode("utf-8")


def parse_latin_font_faces(css_text):
    """Parse CSS for latin @font-face blocks and extract metadata + URL.

    Returns list of dicts with keys: family, weight, style, url
    """
    results = []

    # Split into blocks by looking for /* latin */ comment followed by @font-face
    # Google Fonts CSS2 uses comments like /* latin */ before each @font-face block
    parts = re.split(r'/\*\s*([^*]+?)\s*\*/', css_text)

    # parts alternates: [text_before, comment1, text_after1, comment2, text_after2, ...]
    i = 1
    while i < len(parts):
        subset_label = parts[i].strip()
        block_text = parts[i + 1] if i + 1 < len(parts) else ""
        i += 2

        if subset_label != "latin":
            continue

        # Extract the @font-face block
        face_match = re.search(r'@font-face\s*\{([^}]+)\}', block_text)
        if not face_match:
            continue

        face_body = face_match.group(1)

        # Extract font-family
        family_match = re.search(r"font-family:\s*'([^']+)'", face_body)
        if not family_match:
            continue
        family = family_match.group(1)

        # Extract font-weight
        weight_match = re.search(r'font-weight:\s*(\d+)', face_body)
        weight = weight_match.group(1) if weight_match else "400"

        # Extract font-style
        style_match = re.search(r'font-style:\s*(\w+)', face_body)
        style = style_match.group(1) if style_match else "normal"

        # Extract woff2 URL
        url_match = re.search(r"url\(([^)]+\.woff2[^)]*)\)", face_body)
        if not url_match:
            continue
        font_url = url_match.group(1)

        results.append({
            "family": family,
            "weight": weight,
            "style": style,
            "url": font_url,
        })

    return results


def font_filename(family, weight, style):
    """Generate filename: {family}-{weight}{-italic}.woff2"""
    # Normalize family name: "Source Serif 4" -> "source-serif-4"
    slug = family.lower().replace(" ", "-")
    suffix = "-italic" if style == "italic" else ""
    return f"{slug}-{weight}{suffix}.woff2"


def download_font(url, dest_path):
    """Download a font file."""
    req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT})
    with urllib.request.urlopen(req) as resp:
        data = resp.read()
    with open(dest_path, "wb") as f:
        f.write(data)
    return len(data)


def main():
    os.makedirs(FONTS_DIR, exist_ok=True)

    downloaded = []

    for css_url in FONT_REQUESTS:
        print(f"\nFetching CSS: {css_url[:80]}...")
        css_text = fetch_css(css_url)

        faces = parse_latin_font_faces(css_text)
        print(f"  Found {len(faces)} latin @font-face block(s)")

        for face in faces:
            filename = font_filename(face["family"], face["weight"], face["style"])
            dest = os.path.join(FONTS_DIR, filename)

            print(f"  Downloading {filename}...", end=" ")
            size = download_font(face["url"], dest)
            print(f"({size:,} bytes)")
            downloaded.append(filename)

    print(f"\nDone! Downloaded {len(downloaded)} font files to src/fonts/:")
    for f in sorted(downloaded):
        print(f"  {f}")


if __name__ == "__main__":
    main()
