"""XML/XSD/SVG/XSLT parser — extracts named elements, ids, and includes."""

from __future__ import annotations

import re
from xml.etree import ElementTree as ET

from codectx.parser.types import DependencyRecord, EntityRecord, ParseResult

_INCLUDE_RE  = re.compile(r"""(?:xsi:schemaLocation|xs:include schemaLocation|xsl:import href|xsl:include href|xi:include href)\s*=\s*["']([^"']+)["']""", re.MULTILINE)
_INS_HREF    = re.compile(r"""<\?xml-stylesheet[^?]*href=["']([^"']+)["']""", re.MULTILINE)


def _strip_ns(tag: str) -> str:
    return tag.split("}")[-1] if "}" in tag else tag


def parse_xml(file_path: str, content: str) -> ParseResult:
    result = ParseResult(file_path=file_path, language="xml")

    for m in _INCLUDE_RE.finditer(content):
        path = m.group(1).strip()
        result.dependencies.append(DependencyRecord(path=path, type="include",
            line_number=content[:m.start()].count("\n") + 1, is_local=True))
    for m in _INS_HREF.finditer(content):
        result.dependencies.append(DependencyRecord(path=m.group(1), type="stylesheet",
            line_number=content[:m.start()].count("\n") + 1, is_local=True))

    try:
        root = ET.fromstring(content)
    except ET.ParseError:
        return result

    def _walk(node: ET.Element, depth: int = 0) -> None:
        tag = _strip_ns(node.tag)
        name = node.attrib.get("name") or node.attrib.get("id") or (tag if depth == 0 else None)
        if name:
            result.entities.append(EntityRecord(
                name=name, qualified_name=name, type=tag,
                start_line=1, end_line=1, language="xml",
            ))
        if depth < 3:
            for child in node:
                _walk(child, depth + 1)

    _walk(root)
    return result
