"""Utilities for extracting content from XML-like tags in LLM output."""

from __future__ import annotations

import re
from functools import lru_cache


@lru_cache(maxsize=32)
def _get_tag_pattern(tag: str, *, case_insensitive: bool) -> re.Pattern[str]:
    """Get or create a compiled regex pattern for extracting tag content."""
    flags = re.DOTALL | (re.IGNORECASE if case_insensitive else 0)
    return re.compile(rf"<{tag}>(.*?)</{tag}>", flags)


def extract_xml_tag(content: str, tag: str, *, case_insensitive: bool = True) -> str | None:
    """Extract content from an XML-like tag in LLM output.

    Args:
        content: The string to search in.
        tag: The tag name (without angle brackets).
        case_insensitive: Whether to match tags case-insensitively (default True).

    Returns:
        The content between the tags, or None if not found.

    Example:
        >>> extract_xml_tag("<explain>This is the explanation</explain>", "explain")
        'This is the explanation'

    """
    pattern = _get_tag_pattern(tag, case_insensitive=case_insensitive)
    match = pattern.search(content)
    return match.group(1) if match else None
