"""Parser for git log output."""

import re
import subprocess
from typing import List
from ..models import FailureRecord

_FIX_PREFIXES = re.compile(
    r"^(fix|bug|revert|mistake|error|wrong|broken)(\(.*?\))?:\s*(.+)$",
    re.IGNORECASE,
)

_AGENT_KEYWORDS = re.compile(
    r"\b(agent|claude|codex|gpt|copilot|llm|ai)\b",
    re.IGNORECASE,
)

_NEGATIVE_KEYWORDS = re.compile(
    r"\b(broke|wrong|incorrect|reverted|failed|mistake|error|bad|broken|oops|undo|revert)\b",
    re.IGNORECASE,
)

# Git log oneline format: hash message
_ONELINE_FORMAT = re.compile(r"^[0-9a-f]{7,40}\s+(.+)$", re.IGNORECASE)


class GitLogParser:
    """Parse git log output into FailureRecord objects."""

    def parse(self, text: str) -> List[FailureRecord]:
        """Parse git log text and return failure records."""
        records = []
        for line in text.splitlines():
            line = line.strip()
            if not line:
                continue

            # Extract commit message (handles both oneline and plain message)
            message = line
            m = _ONELINE_FORMAT.match(line)
            if m:
                message = m.group(1).strip()

            record = self._classify_commit(message, line)
            if record:
                records.append(record)

        return records

    def _classify_commit(self, message: str, raw: str) -> "FailureRecord | None":
        """Classify a commit message and return a FailureRecord if relevant."""
        # Check fix-style prefixes
        fix_match = _FIX_PREFIXES.match(message)
        if fix_match:
            prefix = fix_match.group(1).lower()
            description = fix_match.group(3)
            return FailureRecord(
                type=f"git-{prefix}",
                message=description,
                context=message,
                raw=raw,
            )

        # Check agent + negative keyword pattern
        if _AGENT_KEYWORDS.search(message) and _NEGATIVE_KEYWORDS.search(message):
            return FailureRecord(
                type="git-agent-error",
                message=message,
                context=message,
                raw=raw,
            )

        return None

    @classmethod
    def from_repo(cls, repo_path: str = ".", limit: int = 100) -> List[FailureRecord]:
        """Run git log on a repo and parse the output."""
        try:
            result = subprocess.run(
                ["git", "log", f"--max-count={limit}", "--oneline", "--no-merges"],
                cwd=repo_path,
                capture_output=True,
                text=True,
                timeout=30,
            )
            if result.returncode != 0:
                return []
            parser = cls()
            return parser.parse(result.stdout)
        except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
            return []
