"""
Error Analysis and Classification Helpers

Provides error extraction, classification, and fix suggestions for Go and Python tests.
"""

import re
from typing import Optional


# ==============================================================================
# Go Error Helpers
# ==============================================================================

def extract_go_error(output: str) -> str:
    """Extrahiert die Fehlermeldung aus Go-Test-Output"""
    if not output:
        return ""

    lines = output.strip().split("\n")
    error_lines = []

    for line in lines:
        # Typische Go-Fehlermuster
        if "Error:" in line or "FAIL" in line or "panic:" in line:
            error_lines.append(line.strip())
        elif line.strip().startswith("---"):
            continue
        elif "expected" in line.lower() or "got" in line.lower():
            error_lines.append(line.strip())
        elif ".go:" in line:
            error_lines.append(line.strip())

    return " | ".join(error_lines[:3]) if error_lines else output[:200]


def classify_go_error(error_msg: str) -> str:
    """Klassifiziert einen Go-Fehler"""
    if not error_msg:
        return "unknown"

    error_lower = error_msg.lower()
    if "nil pointer" in error_lower or "panic" in error_lower:
        return "nil_pointer"
    elif "expected" in error_lower and "got" in error_lower:
        return "assertion"
    elif "timeout" in error_lower:
        return "timeout"
    elif "connection" in error_lower or "dial" in error_lower:
        return "network"
    elif "not found" in error_lower or "does not exist" in error_lower:
        return "not_found"
    elif "permission" in error_lower or "unauthorized" in error_lower:
        return "permission"
    return "logic_error"


def suggest_go_fix(error_msg: str) -> str:
    """Gibt einen Loesungsvorschlag fuer Go-Fehler"""
    error_type = classify_go_error(error_msg)

    suggestions = {
        "nil_pointer": "Pruefe ob alle Pointer initialisiert sind. Fuege nil-Checks hinzu.",
        "assertion": "Vergleiche die erwarteten mit den tatsaechlichen Werten. Pruefe die Test-Eingabedaten.",
        "timeout": "Erhoehe das Timeout oder optimiere die Funktion. Pruefe Netzwerkverbindungen.",
        "network": "Pruefe ob der Service erreichbar ist. Stelle sicher dass Mocks korrekt konfiguriert sind.",
        "not_found": "Pruefe ob die erwarteten Ressourcen existieren. Aktualisiere Test-Fixtures.",
        "permission": "Pruefe Berechtigungen und Auth-Token im Test-Setup.",
        "logic_error": "Pruefe die Geschaeftslogik und die Test-Annahmen.",
        "unknown": "Analysiere den Stack-Trace fuer mehr Details.",
    }
    return suggestions.get(error_type, suggestions["unknown"])


# ==============================================================================
# Python Error Helpers
# ==============================================================================

def extract_pytest_error(output: str, test_name: str) -> str:
    """Extrahiert die Fehlermeldung aus pytest-Output"""
    if not output:
        return ""

    # Suche nach dem Fehler-Block fuer diesen Test
    pattern = rf'FAILED.*{re.escape(test_name)}.*?\n(.*?)(?=FAILED|PASSED|====|$)'
    match = re.search(pattern, output, re.DOTALL)

    if match:
        error_block = match.group(1)
        # Extrahiere die relevanten Zeilen
        lines = [l.strip() for l in error_block.split("\n") if l.strip()]
        # Suche nach AssertionError oder Exception
        for i, line in enumerate(lines):
            if "AssertionError" in line or "Error" in line or "Exception" in line:
                return " | ".join(lines[max(0, i-1):min(len(lines), i+3)])

    return ""


def classify_pytest_error(error_msg: str) -> str:
    """Klassifiziert einen Python-Fehler"""
    if not error_msg:
        return "unknown"

    if "AssertionError" in error_msg:
        return "assertion"
    elif "TypeError" in error_msg:
        return "type_error"
    elif "AttributeError" in error_msg:
        return "attribute_error"
    elif "KeyError" in error_msg:
        return "key_error"
    elif "ValueError" in error_msg:
        return "value_error"
    elif "ImportError" in error_msg or "ModuleNotFoundError" in error_msg:
        return "import_error"
    elif "ConnectionError" in error_msg or "timeout" in error_msg.lower():
        return "network"
    return "logic_error"


def suggest_pytest_fix(error_msg: str) -> str:
    """Gibt einen Loesungsvorschlag fuer Python-Fehler"""
    error_type = classify_pytest_error(error_msg)

    suggestions = {
        "assertion": "Pruefe die erwarteten vs. tatsaechlichen Werte. Sind die Test-Daten aktuell?",
        "type_error": "Pruefe die Typen der uebergebenen Argumente. Evtl. fehlt eine Typkonvertierung.",
        "attribute_error": "Das Objekt hat dieses Attribut nicht. Pruefe die Initialisierung.",
        "key_error": "Der Schluessel existiert nicht im Dict. Pruefe die Test-Daten.",
        "value_error": "Ungueltiger Wert uebergeben. Pruefe die Eingabeparameter.",
        "import_error": "Modul nicht gefunden. Pruefe die Abhaengigkeiten und den Pfad.",
        "network": "Netzwerkfehler. Sind alle Services gestartet? Sind Mocks konfiguriert?",
        "logic_error": "Logikfehler. Pruefe die Geschaeftslogik und Test-Annahmen.",
        "unknown": "Analysiere den Stack-Trace fuer mehr Details.",
    }
    return suggestions.get(error_type, suggestions["unknown"])
