"""YAML task loader."""

import re
from pathlib import Path
from typing import Optional

import yaml

from agentgog.zz_models import Task


class TaskLoadError(Exception):
    """Raised when task loading fails."""
    pass


def load_task(yaml_file: str) -> Task:
    """Load a task from a YAML file.
    
    YAML format with front matter:
    ---
    id: calcpi_01
    validate: exact
    expected: "0.12345"
    model: google/gemma-3-27b-it:free
    provider: openrouter
    ---
    Calculate the value of (sqrt(pi/3)/1.0201219 -1 )*1000 on 5 decimal places
    
    Args:
        yaml_file: Path to the YAML file
        
    Returns:
        Task object
        
    Raises:
        TaskLoadError: If the file cannot be loaded or parsed
    """
    path = Path(yaml_file)
    
    if not path.exists():
        raise TaskLoadError(f"Task file not found: {yaml_file}")
    
    content = path.read_text()
    
    # Parse front matter
    front_matter_match = re.match(r'^---\s*\n(.*?)\n---\s*\n?(.*)$', content, re.DOTALL)
    
    if not front_matter_match:
        raise TaskLoadError(f"Invalid YAML format in {yaml_file}: missing front matter")
    
    front_matter = front_matter_match.group(1)
    question = front_matter_match.group(2).strip()
    
    try:
        metadata = yaml.safe_load(front_matter) or {}
    except yaml.YAMLError as e:
        raise TaskLoadError(f"Failed to parse YAML front matter: {e}")
    
    # Required fields
    required = ['id', 'validate', 'expected']
    missing = [f for f in required if f not in metadata]
    if missing:
        raise TaskLoadError(f"Missing required fields: {', '.join(missing)}")
    
    # Validate validation type
    valid_types = ['exact', 'semantic', 'numeric']
    if metadata['validate'] not in valid_types:
        raise TaskLoadError(f"Invalid validation type '{metadata['validate']}'. Must be one of: {', '.join(valid_types)}")
    
    return Task(
        id=metadata['id'],
        question=question,
        expected=str(metadata['expected']),
        validate=metadata['validate'],
        model=metadata.get('model'),
        provider=metadata.get('provider'),
        category=metadata.get('category'),
        difficulty=metadata.get('difficulty'),
        timeout=metadata.get('timeout'),
        metadata={k: v for k, v in metadata.items() if k not in [
            'id', 'validate', 'expected', 'model', 'provider', 'category', 'difficulty', 'timeout'
        ]}
    )
