"""Plain text (.txt) and log (.log) -> PDF. Decode ladder (no mojibake on legacy files, never raises): 1. strict UTF-8 -> valid UTF-8 is never second-guessed 2. strict windows-1252 -> its 5 undefined byte holes (0x81/8D/8F/90/9D) make a successful strict decode a reliable cp1252 signal (covers latin-1-ish content too) 3. charset-normalizer -> best guess for other legacy encodings 4. UTF-8 errors=replace -> last resort, total losslessness guarantee Empty / whitespace-only input is a job error ("empty file: ..."). The text is wrapped in
 with PRE_CSS (monospace, wrapped, A4) so line structure
and indentation survive the render.
"""
from __future__ import annotations

from pathlib import Path

from . import common


def decode_bytes(raw: bytes) -> str:
    """Best-effort decode ladder; see module docstring."""
    try:
        return raw.decode("utf-8")
    except UnicodeDecodeError:
        pass
    try:
        return raw.decode("cp1252")
    except UnicodeDecodeError:
        pass
    from charset_normalizer import from_bytes

    best = from_bytes(raw).best()
    if best is not None:
        return str(best)
    return raw.decode("utf-8", errors="replace")


def convert(path: Path, job_id: str, progress_cb=None, output_dir=None,
            source_name=None) -> str:
    """Render a plain-text or log file to a monospace PDF."""
    raw = path.read_bytes()
    if not raw.strip():
        raise ValueError("empty file: nothing to convert")
    text = decode_bytes(raw)

    def _build():
        return f"
{common.escape(text)}
", path.name return common.convert_single( path, job_id, build_html=_build, css=common.PRE_CSS, progress_cb=progress_cb, output_dir=output_dir, name_src=source_name or path.name, )