"""
Format Classifier — routes files to the correct parser based on MIME type
and content-level analysis (e.g. PDF subtype detection).

Quarantine stage handles security checks and returns the detected MIME type.
Classifier uses that MIME type + lightweight content probing to determine
the full (mime_type, subtype) routing key.
"""

from __future__ import annotations

from pathlib import Path

# MIME type → (mime_type, subtype) routing key
# subtype=None means no further discrimination needed
MIME_ROUTING: dict[str, tuple[str, str | None]] = {
    "application/pdf": ("application/pdf", None),  # subtype resolved by probe
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document": (
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        None,
    ),
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": (
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        None,
    ),
    "application/vnd.openxmlformats-officedocument.presentationml.presentation": (
        "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        None,
    ),
    "text/html": ("text/html", None),
    "text/plain": ("text/plain", None),
    "text/csv": ("text/csv", None),
    "text/x-csv": ("text/csv", None),
    "application/csv": ("text/csv", None),
    "text/markdown": ("text/markdown", None),
    "text/x-markdown": ("text/markdown", None),
    "application/epub+zip": ("application/epub+zip", None),
    "application/json": ("application/json", None),
    "text/xml": ("text/xml", None),
    "application/xml": ("text/xml", None),
    "audio/mpeg": ("audio/mpeg", None),
    "audio/wav": ("audio/wav", None),
    "audio/x-wav": ("audio/wav", None),
    "audio/mp4": ("audio/mp4", None),
    "audio/m4a": ("audio/mp4", None),
    "audio/flac": ("audio/flac", None),
    "audio/ogg": ("audio/ogg", None),
    "audio/x-flac": ("audio/flac", None),
    "text/x-tex": ("text/x-tex", None),
    "application/x-tex": ("text/x-tex", None),
}

# Extension fallback when MIME detection is ambiguous
EXTENSION_ROUTING: dict[str, str] = {
    ".pdf": "application/pdf",
    ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    ".html": "text/html",
    ".htm": "text/html",
    ".txt": "text/plain",
    ".csv": "text/csv",
    ".md": "text/markdown",
    ".markdown": "text/markdown",
    ".epub": "application/epub+zip",
    ".json": "application/json",
    ".xml": "text/xml",
    ".mp3": "audio/mpeg",
    ".wav": "audio/wav",
    ".m4a": "audio/mp4",
    ".flac": "audio/flac",
    ".ogg": "audio/ogg",
    ".tex": "text/x-tex",
}


def _detect_pdf_subtype(path: Path) -> str:
    """
    Lightweight probe to classify PDF as digital, scientific, or scanned.
    Only reads page 1 text — does not load the full document.
    """
    try:
        import pymupdf  # type: ignore[import-untyped]

        doc = pymupdf.open(str(path))
        try:
            if doc.page_count == 0:
                return "digital"
            page = doc[0]
            text = page.get_text()
            if not text or len(text.strip()) < 50:
                return "scanned"
            # Lightweight scientific heuristic: references section in last 10% of doc
            last_page_idx = max(0, doc.page_count - max(1, doc.page_count // 10))
            ref_text = ""
            for i in range(last_page_idx, doc.page_count):
                ref_text += doc[i].get_text()
            ref_keywords = ("references", "bibliography", "works cited")
            if any(kw in ref_text.lower() for kw in ref_keywords):
                return "scientific"
        finally:
            doc.close()
    except Exception:
        pass
    return "digital"


def classify(path: Path, detected_mime: str) -> tuple[str, str | None]:
    """
    Return the (mime_type, subtype) routing key for this file.

    Args:
        path: Path to the source file
        detected_mime: MIME type from quarantine magic-byte detection

    Returns:
        (mime_type, subtype) tuple for parser registry lookup
    """
    # Generic MIMEs that magic bytes cannot reliably distinguish — prefer extension
    GENERIC_MIMES = {
        "application/octet-stream",
        "text/plain",
        "text/xml",
        "application/xml",
        "text/x-tex",
    }

    mime = detected_mime
    ext = path.suffix.lower()

    # For generic/ambiguous MIME types, let the file extension take precedence
    if mime in GENERIC_MIMES and ext in EXTENSION_ROUTING:
        mime = EXTENSION_ROUTING[ext]

    route = MIME_ROUTING.get(mime)
    if route is None:
        # Try extension-based override as final fallback
        fallback_mime = EXTENSION_ROUTING.get(ext)
        if fallback_mime:
            route = MIME_ROUTING.get(fallback_mime)

    if route is None:
        return (mime, None)

    mime_key, subtype = route

    # PDF subtype classification (lightweight content probe)
    if mime_key == "application/pdf" and subtype is None:
        subtype = _detect_pdf_subtype(path)

    return (mime_key, subtype)
