"""
Go Test Executor

Executes Go tests and parses results.
"""

import os
import json
import subprocess
import asyncio
from pathlib import Path
from typing import Dict

from ..config import check_go_available, get_running_tests
from ..services.error_handling import extract_go_error, classify_go_error, suggest_go_fix


async def run_go_tests(base_path: Path, service_id: str = "") -> Dict:
    """Fuehrt Go-Tests aus (Thread-basiert, blockiert nicht den Event Loop)"""
    running_tests = get_running_tests()

    if not base_path.exists():
        return {"passed": 0, "failed": 0, "total": 0, "output": f"Pfad existiert nicht: {base_path}", "failed_test_ids": []}

    # Prüfe ob Go installiert ist
    go_available = check_go_available()

    if not go_available:
        return {"passed": 0, "failed": 0, "total": 0, "output": "Go nicht installiert - Tests koennen nicht ausgefuehrt werden", "failed_test_ids": []}

    # Initialer Progress-Status
    if service_id:
        running_tests[service_id] = {
            "current_file": "Starte Go-Tests...",
            "files_done": 0,
            "files_total": 1,
            "passed": 0,
            "failed": 0,
            "status": "running"
        }

    def run_go_tests_sync():
        """Laeuft in separatem Thread"""
        try:
            env = os.environ.copy()
            env["GOPATH"] = "/tmp/go"
            env["GOCACHE"] = "/tmp/go-cache"
            env["CGO_ENABLED"] = "0"

            result = subprocess.run(
                ["go", "test", "-v", "-json", "./..."],
                cwd=str(base_path),
                capture_output=True,
                text=True,
                timeout=300,
                env=env,
            )

            passed = failed = 0
            failed_test_ids = []
            test_outputs = {}

            for line in result.stdout.split("\n"):
                if line.strip():
                    try:
                        event = json.loads(line)
                        action = event.get("Action")
                        test_name = event.get("Test", "")
                        pkg = event.get("Package", "")

                        if action == "pass" and test_name:
                            passed += 1
                            if service_id:
                                running_tests[service_id] = {
                                    "current_file": f"{test_name}",
                                    "files_done": 1,
                                    "files_total": 1,
                                    "passed": passed,
                                    "failed": failed,
                                    "status": "running"
                                }
                        elif action == "fail" and test_name:
                            failed += 1
                            test_key = f"{pkg}::{test_name}"
                            error_output = test_outputs.get(test_key, "")
                            error_message = extract_go_error(error_output)
                            failed_test_ids.append({
                                "id": test_key,
                                "name": test_name,
                                "package": pkg,
                                "file_path": pkg.replace("github.com/", ""),
                                "error_message": error_message or "Test fehlgeschlagen - keine Details",
                                "error_type": classify_go_error(error_message),
                                "suggestion": suggest_go_fix(error_message),
                            })
                            if service_id:
                                running_tests[service_id] = {
                                    "current_file": f"{test_name}",
                                    "files_done": 1,
                                    "files_total": 1,
                                    "passed": passed,
                                    "failed": failed,
                                    "status": "running"
                                }
                        elif action == "output" and test_name:
                            test_key = f"{pkg}::{test_name}"
                            test_outputs[test_key] = test_outputs.get(test_key, "") + event.get("Output", "")
                    except json.JSONDecodeError:
                        pass

            return {
                "passed": passed,
                "failed": failed,
                "total": passed + failed,
                "output": result.stdout[:5000] if result.stdout else result.stderr[:5000],
                "failed_test_ids": failed_test_ids,
            }
        except subprocess.TimeoutExpired:
            return {"passed": 0, "failed": 0, "total": 0, "output": "Timeout nach 5 Minuten", "failed_test_ids": []}
        except Exception as e:
            return {"passed": 0, "failed": 0, "total": 0, "output": str(e), "failed_test_ids": []}

    loop = asyncio.get_event_loop()
    result = await loop.run_in_executor(None, run_go_tests_sync)

    # Finaler Status
    if service_id:
        running_tests[service_id] = {
            "current_file": "Abgeschlossen",
            "files_done": 1,
            "files_total": 1,
            "passed": result.get("passed", 0),
            "failed": result.get("failed", 0),
            "status": "completed"
        }

    return result
