"""Base data structures shared by all parsers."""

from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from typing import Optional


class EntityType(Enum):
    MODULE = "module"
    CLASS = "class"
    FUNCTION = "function"
    METHOD = "method"
    INTERFACE = "interface"
    STRUCT = "struct"
    ENUM = "enum"
    TRAIT = "trait"
    CONSTANT = "constant"
    VARIABLE = "variable"
    DECORATOR = "decorator"
    ENDPOINT = "endpoint"       # HTTP route / API endpoint


@dataclass
class ParsedEntity:
    """A single code entity (class, function, etc.)."""

    name: str
    entity_type: EntityType
    line_start: int
    line_end: int
    docstring: str = ""
    decorators: list[str] = field(default_factory=list)
    parameters: list[str] = field(default_factory=list)
    return_type: str = ""
    parent: Optional[str] = None          # e.g. class name for methods
    visibility: str = "public"            # public / private / protected


@dataclass
class ImportInfo:
    """A single import statement."""

    module: str             # e.g. "os.path" or "react"
    names: list[str]        # e.g. ["join", "dirname"] or ["useState"]
    alias: str = ""         # e.g. "np" for "import numpy as np"
    is_relative: bool = False


@dataclass
class ParsedFile:
    """Complete parse result for a single source file."""

    file_path: str
    language: str
    entities: list[ParsedEntity] = field(default_factory=list)
    imports: list[ImportInfo] = field(default_factory=list)
    exports: list[str] = field(default_factory=list)
    raw_summary: str = ""       # first N lines or docstring at top
    line_count: int = 0
    errors: list[str] = field(default_factory=list)

    @property
    def classes(self) -> list[ParsedEntity]:
        return [e for e in self.entities if e.entity_type in (EntityType.CLASS, EntityType.STRUCT, EntityType.INTERFACE)]

    @property
    def functions(self) -> list[ParsedEntity]:
        return [e for e in self.entities if e.entity_type in (EntityType.FUNCTION, EntityType.METHOD)]

    @property
    def endpoints(self) -> list[ParsedEntity]:
        return [e for e in self.entities if e.entity_type == EntityType.ENDPOINT]


def extract_summary(source: str) -> str:
    """Extract the leading comment/docstring block from source code.

    Shared by both the regex and tree-sitter parsers.
    """
    lines = source.split("\n")[:15]
    summary: list[str] = []
    for line in lines:
        s = line.strip()
        if s.startswith(("#", "//", "/*", "*", '"""', "'''", ";;", "--")):
            summary.append(s)
        elif not s:
            if summary:
                break
        else:
            break
    return "\n".join(summary[:10])
