#!/usr/bin/env python3
"""Synthetic PDF fixture generator for file-remediation Phase 2 heavy tests.

No faculty content (plan §9, R11 — synthetic fixtures only). Deterministic:
PyMuPDF does not stamp creation/mod dates unless explicitly set, and nothing
here reads the clock.

macOS-only: embeds a real system font (Arial, via PyMuPDF's simple-font path,
set_simple=True) so the PDF/UA-1 font-embedding rules (7.21.4.1/7.21.3.2) are
satisfiable by pdf_tree_edit.set_metadata's metadata-only pass, matching the
verified reference recipe (docs/plan-file-remediation-skill.md §10). Base-14
fonts (fitz "helv"/"hebo") are never embedded and would fail those rules
regardless of remediation — this is why fixtures below always insert_font an
on-disk TTF rather than using a base-14 fontname directly.
"""

from __future__ import annotations

from pathlib import Path

import fitz  # PyMuPDF

_FONT_CANDIDATES = [
    ("/System/Library/Fonts/Supplemental/Arial.ttf",
     "/System/Library/Fonts/Supplemental/Arial Bold.ttf"),
]


def find_fonts():
    """Return (regular_ttf, bold_ttf) paths, or raise if none found."""
    for regular, bold in _FONT_CANDIDATES:
        if Path(regular).exists() and Path(bold).exists():
            return regular, bold
    raise RuntimeError(
        "No embeddable system font found (expected Arial under "
        "/System/Library/Fonts/Supplemental) — this fixture generator is macOS-only"
    )


def _page_number(page, n, regular):
    page.insert_font(fontname="FPN", fontfile=regular, set_simple=True)
    page.insert_text((300, 770), str(n), fontsize=9, fontname="FPN")


def build_fixture(path):
    """4-page synthetic untagged PDF: title (H1), a heading (H2), body
    paragraphs (>100 chars each so Assess classifies these pages as text,
    not image-only), one embedded image, a page number per page, and one
    near-zero-text scanned-sim page. Assess-classifies as digital-untagged
    (route E2-insitu). Returns path."""
    regular, bold = find_fonts()
    doc = fitz.open()

    p1 = doc.new_page(width=612, height=792)
    p1.insert_font(fontname="FB", fontfile=bold, set_simple=True)
    p1.insert_font(fontname="FR", fontfile=regular, set_simple=True)
    p1.insert_text((72, 72), "Accessibility Fixture Document", fontsize=24, fontname="FB")
    p1.insert_text((72, 120), "Section One Overview", fontsize=18, fontname="FB")
    p1.insert_text((72, 160),
                    "This synthetic fixture exists to exercise the file-remediation "
                    "Engine E2 pipeline end to end without any faculty content.",
                    fontsize=11, fontname="FR")
    p1.insert_text((72, 190),
                    "A second paragraph adds more real extractable text so this page "
                    "is not misclassified as image-only during Assess classification.",
                    fontsize=11, fontname="FR")
    w, h = 12, 12
    pix = fitz.Pixmap(fitz.csRGB, w, h, bytes([180, 60, 60] * w * h), False)
    p1.insert_image(fitz.Rect(72, 220, 172, 320), pixmap=pix)
    _page_number(p1, 1, regular)

    p2 = doc.new_page(width=612, height=792)
    p2.insert_font(fontname="FR", fontfile=regular, set_simple=True)
    p2.insert_text((72, 100),
                    "Page two carries only body text so the classifier sees enough "
                    "extractable characters here too, keeping it out of the image-only bucket.",
                    fontsize=11, fontname="FR")
    _page_number(p2, 2, regular)

    p3 = doc.new_page(width=612, height=792)
    p3.insert_font(fontname="FR", fontfile=regular, set_simple=True)
    p3.insert_text((72, 100),
                    "Page three closes out the readable content block before the "
                    "near-zero-text page that follows, simulating a scanned page mixed in.",
                    fontsize=11, fontname="FR")
    _page_number(p3, 3, regular)

    # Page 4: near-zero text (scanned-sim) — rasterize a text line onto an
    # image, place it with no underlying text layer at all.
    render_doc = fitz.open()
    rp = render_doc.new_page(width=612, height=792)
    rp.insert_font(fontname="FR", fontfile=regular, set_simple=True)
    rp.insert_text((72, 100), "Scanned page content lives only in pixels on this page.",
                    fontsize=14, fontname="FR")
    raster = rp.get_pixmap(dpi=150)
    p4 = doc.new_page(width=612, height=792)
    p4.insert_image(fitz.Rect(0, 0, 612, 792), pixmap=raster)
    render_doc.close()

    doc.save(str(path))
    doc.close()
    return path


def build_scanned_fixture(path, lines=None):
    """All-image (near-zero extractable text on every page) fixture — Assess
    classifies as scanned (route OCR+E2). Returns path."""
    regular, _ = find_fonts()
    lines = lines or [
        "This first scanned page has real words baked into pixels only.",
        "This second scanned page also carries no underlying text layer.",
    ]
    doc = fitz.open()
    for line in lines:
        render_doc = fitz.open()
        rp = render_doc.new_page(width=612, height=792)
        rp.insert_font(fontname="FR", fontfile=regular, set_simple=True)
        rp.insert_text((72, 100), line, fontsize=14, fontname="FR")
        raster = rp.get_pixmap(dpi=150)
        page = doc.new_page(width=612, height=792)
        page.insert_image(fitz.Rect(0, 0, 612, 792), pixmap=raster)
        render_doc.close()
    doc.save(str(path))
    doc.close()
    return path
