#!/usr/bin/env python3
"""
Wire each marketing page's <Head> block to its per-page OG image.

Replaces `${app_url}/og-image.png` with `${app_url}/og-{name}-v2.png` inside
Open Graph and Twitter Card meta tags. Leaves Schema.org JSON-LD logo URLs
alone (those should keep pointing at the default).

Idempotent: running it twice is a no-op.

Usage:
    python3 scripts/branding/wire_og_images.py
"""

from __future__ import annotations

import re
import sys
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[2]
PAGES_DIR = REPO_ROOT / "resources" / "js" / "Pages"

# (relative_path, og_slug) — slug must match a generated og-{slug}-v2.png in /public/og/
PAGE_MAP: list[tuple[str, str]] = [
    ("Welcome.tsx", "welcome"),
    ("Marketing/Pricing.tsx", "pricing"),
    ("Marketing/Features.tsx", "features"),
    ("Marketing/FreeAudit.tsx", "free-audit"),
    ("Marketing/UseCases/Agencies.tsx", "use-cases-agencies"),
    ("Marketing/UseCases/Bloggers.tsx", "use-cases-bloggers"),
    ("Marketing/UseCases/Ecommerce.tsx", "use-cases-ecommerce"),
    ("Marketing/UseCases/Consultants.tsx", "use-cases-consultants"),
    ("Marketing/Roadmap.tsx", "roadmap"),
    ("Marketing/Changelog.tsx", "changelog"),
    ("Marketing/Press.tsx", "press"),
    ("Marketing/CaseStudies/Index.tsx", "case-studies"),
    ("Marketing/Learn/Hub.tsx", "learn"),
    ("Marketing/Blog/Index.tsx", "blog"),
    ("Marketing/Compare.tsx", "compare"),
    ("Marketing/Privacy.tsx", "privacy"),
    ("Marketing/Terms.tsx", "terms"),
    ("Marketing/Dpa.tsx", "dpa"),
    ("Marketing/SubProcessors.tsx", "sub-processors"),
]

# Match og:image + twitter:image meta tags, NOT schema.org logo URLs.
META_PATTERN = re.compile(
    r'(<meta\s+[^>]*?(?:property="og:image"|name="twitter:image")[^>]*?content=\{`\$\{app_url\}/)'
    r'og-image\.png'
    r'(`\}\s*/?>)',
    re.DOTALL,
)


def patch_file(path: Path, slug: str) -> int:
    """Replace og-image.png → og-{slug}-v2.png inside og:image / twitter:image meta tags."""
    if not path.exists():
        print(f"  ! missing: {path.relative_to(REPO_ROOT)}")
        return 0
    src = path.read_text(encoding="utf-8")
    new_target = f"og-{slug}-v2.png"
    if new_target in src and "og-image.png" not in src:
        # Already migrated; nothing to do.
        return 0
    new_src, n = META_PATTERN.subn(rf"\1{new_target}\2", src)
    if n == 0:
        print(f"  - no og:image/twitter:image meta found: {path.relative_to(REPO_ROOT)}")
        return 0
    path.write_text(new_src, encoding="utf-8")
    print(f"  → patched {path.relative_to(REPO_ROOT)} ({n} replacement(s) → {new_target})")
    return n


def assert_assets_exist() -> None:
    """
    Cross-validate PAGE_MAP entries against actual files on disk.

    If we patch `<Head>` to reference og-{slug}-v2.png and that file isn't
    in /public/og/, every social share will show a broken preview. The
    assets are produced by generate_og_images.py — so a missing one here
    means someone added an entry to PAGE_MAP without adding it to PAGES,
    or didn't run the generator.

    Fail fast with a clear remediation message rather than silently
    patching a page to a 404.
    """
    og_dir = REPO_ROOT / "public" / "og"
    missing: list[str] = []
    for _, slug in PAGE_MAP:
        png = og_dir / f"og-{slug}-v2.png"
        if not png.exists():
            missing.append(f"  - {png.relative_to(REPO_ROOT)}")
    if missing:
        print(
            "ERROR: PAGE_MAP entries reference assets that don't exist on disk.\n"
            "Missing:\n" + "\n".join(missing) + "\n\n"
            "Did you forget to run `python3 scripts/branding/generate_og_images.py`\n"
            "after adding a new page? Each PAGE_MAP entry needs a matching entry\n"
            "in generate_og_images.py PAGES.\n",
            file=sys.stderr,
        )
        sys.exit(1)


def main() -> None:
    assert_assets_exist()
    print("Wiring per-page OG images into <Head> blocks…")
    total = 0
    for relpath, slug in PAGE_MAP:
        total += patch_file(PAGES_DIR / relpath, slug)
    print(f"Done. {total} replacements across {len(PAGE_MAP)} pages.")


if __name__ == "__main__":
    main()
