"""Models list parser."""

from pathlib import Path
from typing import List, Optional, Set, Tuple


class ModelEntry:
    """Represents a model entry from models.list."""
    
    def __init__(self, provider: str, model: str):
        self.provider = provider.strip()
        self.model = model.strip()
    
    def __repr__(self):
        return f"ModelEntry(provider='{self.provider}', model='{self.model}')"
    
    def __hash__(self):
        """Make ModelEntry hashable for use in sets."""
        return hash((self.provider, self.model))
    
    def __eq__(self, other):
        """Compare ModelEntry objects."""
        if not isinstance(other, ModelEntry):
            return False
        return self.provider == other.provider and self.model == other.model


def _parse_models_file(filepath: str) -> List[ModelEntry]:
    """Parse a models file (internal helper).
    
    Format: Each line contains "provider model" (space separated)
    Empty lines and lines starting with # are ignored.
    
    Args:
        filepath: Path to models file
        
    Returns:
        List of ModelEntry objects
        
    Raises:
        FileNotFoundError: If file doesn't exist
        ValueError: If a line has invalid format
    """
    path = Path(filepath)
    
    if not path.exists():
        raise FileNotFoundError(f"Models list file not found: {filepath}")
    
    entries = []
    
    with open(path, 'r') as f:
        for line_num, line in enumerate(f, 1):
            line = line.strip()
            
            # Skip empty lines and comments
            if not line or line.startswith('#'):
                continue
            
            # Split by whitespace
            parts = line.split(None, 1)  # Split on any whitespace, max 1 split
            
            if len(parts) != 2:
                raise ValueError(f"Invalid format at line {line_num}: expected 'provider model', got '{line}'")
            
            provider, model = parts
            entries.append(ModelEntry(provider, model))
    
    return entries


def parse_models_list(filepath: str, banned_filepath: Optional[str] = None) -> List[ModelEntry]:
    """Parse models.list file and optionally filter out banned models.
    
    Format: Each line contains "provider model" (space separated)
    Empty lines and lines starting with # are ignored.
    
    Args:
        filepath: Path to models.list file
        banned_filepath: Optional path to models_banned.list file. If provided,
                        models listed in this file will be excluded from results.
        
    Returns:
        List of ModelEntry objects (excluding banned models)
        
    Raises:
        FileNotFoundError: If models.list file doesn't exist
        ValueError: If a line has invalid format
    """
    # Parse main models list
    entries = _parse_models_file(filepath)
    
    # If banned list provided, filter out banned models
    if banned_filepath and Path(banned_filepath).exists():
        banned_entries = _parse_models_file(banned_filepath)
        banned_set = set(banned_entries)
        
        # Filter out banned models
        entries = [entry for entry in entries if entry not in banned_set]
    
    return entries


def parse_banned_models_list(filepath: str) -> Set[ModelEntry]:
    """Parse models_banned.list file.
    
    Args:
        filepath: Path to models_banned.list file
        
    Returns:
        Set of ModelEntry objects representing banned models
        
    Raises:
        FileNotFoundError: If file doesn't exist
    """
    entries = _parse_models_file(filepath)
    return set(entries)
