"""
Job Handler
Processes incoming test jobs from the backend
"""
import tempfile
import shutil
import subprocess
import logging
from pathlib import Path
from typing import Dict, Any, Tuple
from datetime import datetime

from rich.console import Console

from .docker_executor import DockerExecutor, TestResult

console = Console()
logger = logging.getLogger(__name__)


class JobHandler:
    """
    Handles incoming test jobs.
    
    Responsibilities:
    - Clone/checkout repository
    - Set up workspace with test files
    - Execute tests via DockerExecutor
    - Clean up workspace
    """
    
    def __init__(self):
        self.executor = DockerExecutor()
    
    async def handle_job(self, job: Dict[str, Any], signature: str) -> Dict[str, Any]:
        """
        Process a test job.
        
        Args:
            job: Job data from backend
            signature: Job signature for verification
            
        Returns:
            Test result dictionary
        """
        workspace = None
        
        try:
            job_id = job.get("id", "unknown")
            repo_name = job.get("repo_name", "")
            commit_sha = job.get("commit_sha", "")
            test_file = job.get("test_file", "")
            test_content = job.get("test_content", "")
            language = job.get("language", "python")
            
            console.print(f"   Repo: {repo_name}")
            console.print(f"   Commit: {commit_sha[:8] if commit_sha else 'N/A'}")
            
            # Step 1: Create workspace
            workspace = Path(tempfile.mkdtemp(prefix="spectra_"))
            console.print(f"   📁 Workspace: {workspace.name}", style="dim")
            
            # Step 2: Set up repository (Clone if needed)
            if repo_name:
                success = self._clone_repo(workspace, repo_name, commit_sha)
                if not success:
                    return {
                        "status": "error",
                        "error_message": "Failed to clone repository",
                        "tests_run": 0,
                        "tests_passed": 0,
                        "tests_failed": 0
                    }
            
            # Step 2.5: Set up test files
            if test_content:
                # Ensure directories exist for the test file
                test_file_path = workspace / test_file
                test_file_path.parent.mkdir(parents=True, exist_ok=True)
                test_file_path.write_text(test_content)
                console.print(f"   📄 Test file written: {test_file}", style="dim")
            elif not repo_name:
                return {
                    "status": "error",
                    "error_message": "No test content or repository provided",
                    "tests_run": 0,
                    "tests_passed": 0,
                    "tests_failed": 0
                }
            
            # Step 3: Run test
            result = self.executor.run_test(
                workspace=workspace,
                test_file=test_file,
                language=language
            )
            
            # Step 4: Format result
            console.print(f"   Status: [bold]{result.status.upper()}[/bold]")
            if result.tests_run > 0:
                console.print(f"   Tests: {result.tests_passed} passed, {result.tests_failed} failed")
            
            if result.error_message:
                console.print(f"   ❌ Error: {result.error_message}", style="red")
            
            return result.to_dict()
            
        except Exception as e:
            logger.error(f"Job handler error: {e}")
            return {
                "status": "error",
                "error_message": str(e),
                "tests_run": 0,
                "tests_passed": 0,
                "tests_failed": 0
            }
        finally:
            # Cleanup workspace
            if workspace and workspace.exists():
                try:
                    shutil.rmtree(workspace)
                    console.print(f"   🧹 Workspace cleaned", style="dim")
                except Exception as e:
                    logger.warning(f"Failed to cleanup workspace: {e}")
    
    def _clone_repo(self, workspace: Path, repo_name: str, commit_sha: str) -> bool:
        """
        Clone repository at specific commit.
        
        Args:
            workspace: Target directory
            repo_name: GitHub repo (owner/repo)
            commit_sha: Commit to checkout
            
        Returns:
            True if successful
        """
        try:
            console.print(f"   📥 Cloning {repo_name}...", style="dim")
            
            repo_url = f"https://github.com/{repo_name}.git"
            
            # Clone
            result = subprocess.run(
                ["git", "clone", "--depth", "1", repo_url, str(workspace)],
                capture_output=True,
                text=True,
                timeout=60
            )
            
            if result.returncode != 0:
                console.print(f"   ❌ Clone failed: {result.stderr[:100]}", style="red")
                return False
            
            # Checkout specific commit
            if commit_sha and len(commit_sha) > 8:
                subprocess.run(
                    ["git", "fetch", "--depth", "1", "origin", commit_sha],
                    cwd=workspace,
                    capture_output=True,
                    timeout=30
                )
                subprocess.run(
                    ["git", "checkout", commit_sha],
                    cwd=workspace,
                    capture_output=True,
                    timeout=10
                )
            
            console.print(f"   ✓ Repository ready", style="dim")
            return True
            
        except subprocess.TimeoutExpired:
            console.print(f"   ⏱️ Clone timed out", style="yellow")
            return False
        except Exception as e:
            console.print(f"   ❌ Clone error: {e}", style="red")
            return False
