"""XML -> PDF (pretty text dump, monospace). Validation is explicit: lxml must parse the document, otherwise the job fails with "Invalid XML: " (never a render failure). A valid document is rendered as its text content — every text node and tail in document order, one per line, whitespace-only nodes dropped — inside
 with PRE_CSS. Attribute values are intentionally not dumped: the
contract is that element text survives extraction.
"""
from __future__ import annotations

from pathlib import Path

from lxml import etree

from . import common
from .text_converter import decode_bytes


def convert(path: Path, job_id: str, progress_cb=None, output_dir=None,
            source_name=None) -> str:
    """Render an XML file to a monospace text-dump PDF."""
    raw = path.read_bytes()
    if not raw.strip():
        raise ValueError("empty file: nothing to convert")
    text = decode_bytes(raw)
    try:
        root = etree.fromstring(text.encode("utf-8"))
    except etree.XMLSyntaxError as exc:
        raise ValueError(f"Invalid XML: {exc}") from exc

    lines: list[str] = []
    for el in root.iter():
        for chunk in (el.text, el.tail):
            if not chunk:
                continue
            piece = " ".join(chunk.split())
            if piece:
                lines.append(piece)
    if not lines:
        raise ValueError("empty file: XML has no text content")
    body = "\n".join(lines)

    def _build():
        return f"
{common.escape(body)}
", 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, )