"""Command runner for executing agata commands."""

import subprocess
import time
from pathlib import Path
from typing import Optional, Tuple


class RunnerError(Exception):
    """Raised when command execution fails."""
    pass


def run_agata_chat(
    task_file: str,
    provider: str,
    model: str,
    output_file: str,
    timeout: Optional[int] = None
) -> Tuple[bool, str, float]:
    """Run agata chat command with a task file.
    
    Executes: agata chat -f <task_file> --provider <provider> --model <model> -o <output_file>
    
    Args:
        task_file: Path to the YAML task file
        provider: Provider name (e.g., openrouter)
        model: Model name (e.g., google/gemma-3-27b-it:free)
        output_file: Path to save the output
        timeout: Timeout in seconds
        
    Returns:
        Tuple of (success, error_message, execution_time_seconds)
    """
    effective_timeout = timeout or 300  # Default 5 minutes
    
    cmd = [
        'agata', 'chat',
        '-f', task_file,
        '--provider', provider,
        '--model', model,
        '-o', output_file
    ]
    
    start_time = time.time()
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=effective_timeout
        )
        
        elapsed = time.time() - start_time
        
        if result.returncode != 0:
            error_msg = result.stderr.strip() if result.stderr else f"Command failed with code {result.returncode}"
            return False, error_msg, elapsed
        
        return True, "", elapsed
        
    except subprocess.TimeoutExpired:
        elapsed = time.time() - start_time
        return False, f"Command timed out after {effective_timeout} seconds", elapsed
    except FileNotFoundError:
        elapsed = time.time() - start_time
        return False, "Command 'agata' not found. Please install agata.", elapsed
    except Exception as e:
        elapsed = time.time() - start_time
        return False, f"Unexpected error: {str(e)}", elapsed


def run_agata_compare(
    result_file: str,
    task_file: str,
    output_file: str,
    timeout: Optional[int] = None
) -> Tuple[bool, str, float]:
    """Run agata compare command to validate output.
    
    Executes: agata compare -f <result_file> -e <task_file> -o <output_file>
    
    Args:
        result_file: Path to the model output file
        task_file: Path to the YAML task file with expected answer
        output_file: Path to save comparison result
        timeout: Timeout in seconds
        
    Returns:
        Tuple of (success, error_message, execution_time_seconds)
    """
    effective_timeout = timeout or 60  # Default 1 minute for comparison
    
    cmd = [
        'agata', 'compare',
        '-f', result_file,
        '-e', task_file,
        '-o', output_file
    ]
    
    start_time = time.time()
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=effective_timeout
        )
        
        elapsed = time.time() - start_time
        
        if result.returncode != 0:
            error_msg = result.stderr.strip() if result.stderr else f"Compare failed with code {result.returncode}"
            return False, error_msg, elapsed
        
        return True, "", elapsed
        
    except subprocess.TimeoutExpired:
        elapsed = time.time() - start_time
        return False, f"Compare timed out after {effective_timeout} seconds", elapsed
    except FileNotFoundError:
        elapsed = time.time() - start_time
        return False, "Command 'agata' not found. Please install agata.", elapsed
    except Exception as e:
        elapsed = time.time() - start_time
        return False, f"Unexpected error: {str(e)}", elapsed


def read_file_content(file_path: str) -> Optional[str]:
    """Read file content.
    
    Args:
        file_path: Path to the file
        
    Returns:
        File content or None if file doesn't exist
    """
    path = Path(file_path)
    if not path.exists():
        return None
    return path.read_text()
