"""Optional XSD validation for generated C59 XML documents."""

from __future__ import annotations

import importlib
from pathlib import Path

from istat.xml_export.exceptions import XmlPayloadValidationError


def load_default_c59_xsd_path() -> str:
    """Return the conventional module-local path for the C59 XSD file."""

    return str(Path(__file__).resolve().parent / "schemas" / "c59.xsd")


def validate_c59_xml_against_xsd(xml_content: str, xsd_path: str) -> None:
    """Validate C59 XML content against a provided XSD schema path."""

    if not xml_content or not str(xml_content).strip():
        raise XmlPayloadValidationError("xml_content is required for XSD validation")
    if not xsd_path or not str(xsd_path).strip():
        raise XmlPayloadValidationError("xsd_path is required for XSD validation")

    schema_path = Path(xsd_path).expanduser().resolve()
    if not schema_path.exists():
        raise XmlPayloadValidationError(f"XSD schema file not found: {schema_path}")

    try:
        etree = importlib.import_module("lxml.etree")
    except ModuleNotFoundError as exc:
        raise XmlPayloadValidationError(
            "C59 XSD validation requires the optional 'lxml' dependency"
        ) from exc

    try:
        schema_document = etree.parse(str(schema_path))
        schema = etree.XMLSchema(schema_document)
    except (etree.XMLSyntaxError, etree.XMLSchemaParseError) as exc:
        raise XmlPayloadValidationError(f"Invalid XSD schema: {exc}") from exc

    try:
        xml_document = etree.fromstring(xml_content.encode("utf-8"))
    except etree.XMLSyntaxError as exc:
        raise XmlPayloadValidationError(f"Malformed XML content: {exc}") from exc

    if schema.validate(xml_document):
        return

    errors = [
        error.message.strip()
        for error in schema.error_log
        if getattr(error, "message", "").strip()
    ]
    detail = "; ".join(errors) if errors else "XML does not conform to the XSD schema"
    raise XmlPayloadValidationError(f"C59 XML failed XSD validation: {detail}")
