"""CodeEntity — entidad de codigo extraida por analisis AST."""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass
class CodeEntity:
    """Entidad de codigo extraida por analisis AST (tree-sitter).

    Representa una funcion, clase, metodo, tipo, interfaz, struct o trait
    encontrado en codigo fuente. Las clases contienen sus metodos como children.
    """

    kind: str
    name: str
    start_line: int
    end_line: int
    signature: str
    docstring: str | None
    language: str
    children: list[CodeEntity] = field(default_factory=list)

    @property
    def line_count(self) -> int:
        """Numero de lineas que ocupa la entidad."""
        return self.end_line - self.start_line + 1

    @property
    def has_docstring(self) -> bool:
        """True si la entidad tiene docstring o comentario documentado."""
        return self.docstring is not None and len(self.docstring.strip()) > 0

    def to_dict(self) -> dict:
        """Serializa la entidad a un diccionario de forma recursiva."""
        return {
            "kind": self.kind,
            "name": self.name,
            "start_line": self.start_line,
            "end_line": self.end_line,
            "signature": self.signature,
            "docstring": self.docstring,
            "language": self.language,
            "children": [child.to_dict() for child in self.children],
        }

    @classmethod
    def from_dict(cls, data: dict) -> CodeEntity:
        """Deserializa una entidad desde un diccionario (recursivo)."""
        children = [cls.from_dict(c) for c in data.get("children", [])]
        return cls(
            kind=data["kind"],
            name=data["name"],
            start_line=data["start_line"],
            end_line=data["end_line"],
            signature=data["signature"],
            docstring=data.get("docstring"),
            language=data["language"],
            children=children,
        )
