"""Bash/Shell source parser (regex-based)."""

from __future__ import annotations

import re

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

_FN1_RE     = re.compile(r"^(\s*)function\s+(\w+)\s*(?:\(\s*\))?\s*\{", re.MULTILINE)
_FN2_RE     = re.compile(r"^(\s*)(\w+)\s*\(\s*\)\s*\{", re.MULTILINE)
_SOURCE_RE  = re.compile(r"^\s*(?:source|\.)\s+([\S]+)", re.MULTILINE)
_EXPORT_RE  = re.compile(r"^\s*export\s+(\w+)=", re.MULTILINE)
_VAR_RE     = re.compile(r"^(\w+)=(?!.*#\s*noglob)", re.MULTILINE)
_ALIAS_RE   = re.compile(r"^\s*alias\s+(\w+)=", re.MULTILINE)


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


def parse_bash(file_path: str, content: str) -> ParseResult:
    result = ParseResult(file_path=file_path, language="bash")

    for m in _SOURCE_RE.finditer(content):
        path = m.group(1).strip("'\"")
        result.dependencies.append(DependencyRecord(
            path=path, type="source", line_number=_ln(content, m.start()),
            is_local=not path.startswith("/"),
        ))

    seen_fns: set[str] = set()
    for m in _FN1_RE.finditer(content):
        name = m.group(2)
        if name not in seen_fns:
            seen_fns.add(name)
            result.entities.append(EntityRecord(
                name=name, qualified_name=name, type="function",
                start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
                language="bash",
            ))
    for m in _FN2_RE.finditer(content):
        name = m.group(2)
        if name not in seen_fns:
            seen_fns.add(name)
            result.entities.append(EntityRecord(
                name=name, qualified_name=name, type="function",
                start_line=_ln(content, m.start()), end_line=_ln(content, m.start()),
                language="bash",
            ))

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

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

    return result
