"""Comparison spectrum constants and utilities for agentgog.

This module defines the allowed comparison results from the `agata compare` command
and provides utilities for working with them.

Users can modify the SPECTRUM list to add or remove comparison categories.
"""

from typing import List, Optional


# The spectrum of possible comparison results from `agata compare` command.
# These values represent the semantic relationship between actual and expected outputs.
# Order matters: from most similar to least similar.
SPECTRUM: List[str] = [
    "same",      # Results are semantically identical
    "similar",   # Results are close but have minor differences
    "differ",    # Results are significantly different
]

# Results that indicate the test passed (semantically equivalent)
PASS_RESULTS: List[str] = ["same", "similar"]

# Result for technical failures (compare command failed to execute)
TECHNICAL_FAILURE: str = "none"


def is_valid_result(result: Optional[str]) -> bool:
    """Check if a comparison result is valid.
    
    Args:
        result: The comparison result string to validate
        
    Returns:
        True if the result is a valid comparison value, False otherwise
        
    Examples:
        >>> is_valid_result("same")
        True
        >>> is_valid_result("similar")
        True
        >>> is_valid_result("none")
        False
        >>> is_valid_result(None)
        False
    """
    if result is None:
        return False
    return result.lower() in SPECTRUM


def is_passing_result(result: Optional[str]) -> bool:
    """Check if a comparison result indicates a passing test.
    
    Args:
        result: The comparison result string to check
        
    Returns:
        True if the result indicates semantic equivalence (same/similar)
        
    Examples:
        >>> is_passing_result("same")
        True
        >>> is_passing_result("similar")
        True
        >>> is_passing_result("differ")
        False
        >>> is_passing_result(None)
        False
    """
    if result is None:
        return False
    return result.lower() in PASS_RESULTS


def normalize_result(result: Optional[str]) -> str:
    """Normalize a comparison result string.

    Attempts to extract a valid comparison value from the input.
    Preserves "none" for technical failures.
    Returns "differ" if the result cannot be normalized to a valid value.

    Args:
        result: Raw comparison result string

    Returns:
        Normalized comparison result from SPECTRUM, "none" for technical failures,
        or "differ" as default

    Examples:
        >>> normalize_result("  SAME  ")
        "same"
        >>> normalize_result("Similar")
        "similar"
        >>> normalize_result("none")
        "none"
        >>> normalize_result("invalid")
        "differ"
    """
    if result is None:
        return "differ"

    normalized = result.strip().lower()

    # Preserve technical failure indicator
    if normalized == TECHNICAL_FAILURE:
        return TECHNICAL_FAILURE

    if normalized in SPECTRUM:
        return normalized

    # Try to find a valid value within the string
    for valid in SPECTRUM:
        if valid in normalized:
            return valid

    return "differ"


def get_all_valid_results() -> List[str]:
    """Get all valid comparison results including technical failure indicator.
    
    Returns:
        List of all possible results that can appear in verification_result field
        
    Examples:
        >>> get_all_valid_results()
        ["same", "similar", "differ", "none"]
    """
    return SPECTRUM + [TECHNICAL_FAILURE]
