Source code for aeat.domain.calculations.registry._legal

"""Legal catalogue helpers."""

from __future__ import annotations

from collections.abc import Mapping
from pathlib import Path

from ._citation_blocklist import CitationSource, find_known_bad
from ._errors import RegistryValidationError
from ._schema import LegalReference
from ._text import normalise_corpus_text

_SOURCE_BY_KIND: dict[str, CitationSource] = {
    "ley": "ley",
    "real_decreto": "reglamento",
    "real_decreto_legislativo": "real_decreto_legislativo",
    "real_decreto_ley": "reglamento",
    "orden": "orden",
    "reglamento": "reglamento",
    "manual": "manual",
    "instruction": "instruction",
}










_LEGAL_CORPUS_CACHE: dict[tuple[str, int, int], str] = {}


def _legal_corpus_text(source_root: Path, reference: LegalReference) -> str:
    path_text = reference.corpus_ref.split("#", 1)[0]
    path = (source_root / path_text).resolve()
    repo_root = source_root.resolve()
    if repo_root not in path.parents and path != repo_root:
        raise RegistryValidationError(f"legal reference {reference.id!r} escapes repository root")
    if not path.is_file():
        raise RegistryValidationError(f"legal reference {reference.id!r} missing corpus file {path_text!r}")
    stat = path.stat()
    cache_key = (str(path), stat.st_size, stat.st_mtime_ns)
    if cache_key in _LEGAL_CORPUS_CACHE:
        return _LEGAL_CORPUS_CACHE[cache_key]

    text = normalise_corpus_text(path.read_text(encoding="utf-8", errors="replace"))
    _LEGAL_CORPUS_CACHE[cache_key] = text
    return text