"""Scala source parser (regex-based)."""

from __future__ import annotations

import re

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

_IMPORT_RE  = re.compile(r"^\s*import\s+([\w.*{},\s]+)", re.MULTILINE)
_CLASS_RE   = re.compile(r"^(\s*)(?:(?:abstract|sealed|final|case|implicit|override)\s+)*(?:class|trait|object|case class|case object|enum)\s+(\w+)", re.MULTILINE)
_DEF_RE     = re.compile(r"^(\s*)(?:(?:abstract|override|implicit|private|protected|final|lazy|inline)\s+)*def\s+(\w+)\s*[[(:]", re.MULTILINE)
_VAL_RE     = re.compile(r"^(\s*)(?:(?:private|protected|override|implicit|lazy|final)\s+)*(?:val|var)\s+(\w+)\s*:", re.MULTILINE)
_TYPE_RE    = re.compile(r"^\s*type\s+(\w+)\s*=", re.MULTILINE)
_GIVEN_RE   = re.compile(r"^\s*(?:given|implicit\s+val)\s+(\w+)\b", re.MULTILINE)


def _ln(content: str, pos: int) -> int:
    return content[:pos].count("\n") + 1


def parse_scala(file_path: str, content: str) -> ParseResult:
    result = ParseResult(file_path=file_path, language="scala")

    for m in _IMPORT_RE.finditer(content):
        path = m.group(1).strip().rstrip(",;").strip()
        result.dependencies.append(DependencyRecord(
            path=path, type="import", line_number=_ln(content, m.start()),
        ))

    for m in _CLASS_RE.finditer(content):
        name = m.group(2)
        text = m.group(0).lower()
        if "trait" in text:
            kind = "trait"
        elif "object" in text:
            kind = "object"
        elif "enum" in text:
            kind = "enum"
        else:
            kind = "class"
        result.entities.append(EntityRecord(
            name=name, qualified_name=name, type=kind,
            start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
            language="scala",
        ))

    for m in _DEF_RE.finditer(content):
        name = m.group(2)
        result.entities.append(EntityRecord(
            name=name, qualified_name=name, type="function",
            start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
            language="scala",
        ))

    for m in _TYPE_RE.finditer(content):
        result.entities.append(EntityRecord(
            name=m.group(1), qualified_name=m.group(1), type="type_alias",
            start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
            language="scala",
        ))

    return result
