"""
Test failure analysis logic for Storm Logger
"""

import json
from typing import Dict, Any, List


def analyze_failure(test_name: str, error_message: str, test_file_path: str) -> str:
    """
    Analyze failing tests and suggest specific fixes based on error patterns and Storm Logger best practices
    
    Args:
        test_name: Name of the failing test (e.g., test_table_printing)
        error_message: Error message from test output
        test_file_path: Path to the test file
        
    Returns:
        JSON string with analysis results and fix suggestions
    """
    analysis = {
        "test_name": test_name,
        "analysis_type": "Storm Logger Test Failure Analysis",
        "error_analysis": {},
        "fix_suggestions": [],
        "storm_commands": [],
        "related_tests": [],
        "confidence": "high"
    }
    
    # Analyze common error patterns
    error_lower = error_message.lower()
    
    # Parameter order issues (like our table printing fix)
    if "takes" in error_lower and "positional argument" in error_lower:
        analysis["error_analysis"] = {
            "category": "Parameter Order Issue",
            "description": "Method called with incorrect parameter order",
            "severity": "medium",
            "common_in": "Storm Logger console methods"
        }
        analysis["fix_suggestions"] = [
            f"Check method signature in {test_file_path}",
            "Verify parameter order matches the actual method definition",
            "Look for methods that expect (title, columns, rows) vs (columns, rows, title=...)",
            "Check similar tests for correct calling patterns"
        ]
        analysis["storm_commands"] = [
            f"./test.sh -k {test_name} -v",
            f"./test.sh -k {test_name.split('_')[1]} --quick"
        ]
        
    # Import/Module errors
    elif "importerror" in error_lower or "modulenotfounderror" in error_lower:
        analysis["error_analysis"] = {
            "category": "Import Error",
            "description": "Module or dependency import failure",
            "severity": "high",
            "common_in": "Storm Logger integrations"
        }
        analysis["fix_suggestions"] = [
            "Check if required dependencies are installed",
            "Verify import paths in test file",
            "Check for circular imports",
            "Ensure Storm Logger modules are properly packaged"
        ]
        
    # Attribute errors (missing methods/properties)
    elif "attributeerror" in error_lower:
        analysis["error_analysis"] = {
            "category": "Attribute Error", 
            "description": "Missing method or property on object",
            "severity": "medium",
            "common_in": "Storm Logger interface implementations"
        }
        analysis["fix_suggestions"] = [
            "Verify the object has the expected method/property",
            "Check if method was renamed or moved",
            "Look at the class definition for available methods",
            "Consider if mocking is needed for the test"
        ]
        
    # Assertion errors
    elif "assertionerror" in error_lower or "assert" in error_lower:
        analysis["error_analysis"] = {
            "category": "Assertion Failure",
            "description": "Test assertion did not pass",
            "severity": "low",
            "common_in": "Storm Logger business logic"
        }
        analysis["fix_suggestions"] = [
            "Review the expected vs actual values",
            "Check if test data setup is correct",
            "Verify business logic implementation",
            "Consider if test expectations need updating"
        ]
        
    # Type errors
    elif "typeerror" in error_lower:
        analysis["error_analysis"] = {
            "category": "Type Error",
            "description": "Type mismatch or incorrect usage",
            "severity": "medium", 
            "common_in": "Storm Logger type annotations"
        }
        analysis["fix_suggestions"] = [
            "Check parameter types match method signature",
            "Verify return type expectations",
            "Look for None values where objects expected",
            "Check type annotations in Storm Logger code"
        ]
        
    else:
        analysis["error_analysis"] = {
            "category": "General Error",
            "description": "Unrecognized error pattern",
            "severity": "unknown",
            "common_in": "Various Storm Logger components"
        }
        analysis["fix_suggestions"] = [
            "Read the full error traceback carefully",
            "Check Storm Logger documentation",
            "Look for similar issues in other tests",
            "Consider creating a minimal reproduction case"
        ]
        analysis["confidence"] = "medium"
    
    # Add generic Storm commands
    if not analysis["storm_commands"]:
        analysis["storm_commands"] = [
            f"./test.sh -k {test_name} -v",
            f"./test.sh -k {test_name.replace('test_', '')} --quick",
            f"./test.sh --failed -v"
        ]
    
    # Suggest related tests to check
    test_class = test_name.split("::")[0] if "::" in test_name else ""
    if test_class:
        analysis["related_tests"] = [
            f"./test.sh -k {test_class}",
            f"./test.sh -k \"console and table\"" if "console" in test_file_path else f"./test.sh -k {test_file_path.split('/')[-1].replace('test_', '').replace('.py', '')}"
        ]
    
    # Add workflow suggestions
    analysis["next_steps"] = [
        "1. Run the specific test with verbose output",
        "2. Check the method signature in the source code", 
        "3. Look at working similar tests for patterns",
        "4. Apply the fix and re-run the test",
        "5. Run related tests to ensure no regressions"
    ]
    
    return json.dumps(analysis, indent=2)


def get_error_patterns() -> Dict[str, Any]:
    """
    Get common error patterns and their solutions
    
    Returns:
        Dictionary with error patterns and solutions
    """
    return {
        "parameter_order": {
            "symptoms": ["takes", "positional argument"],
            "description": "Method called with incorrect parameter order",
            "solutions": [
                "Check method signature",
                "Verify parameter order",
                "Look at similar working tests"
            ]
        },
        "import_error": {
            "symptoms": ["importerror", "modulenotfounderror"],
            "description": "Module or dependency import failure",
            "solutions": [
                "Check dependencies",
                "Verify import paths",
                "Check for circular imports"
            ]
        },
        "attribute_error": {
            "symptoms": ["attributeerror"],
            "description": "Missing method or property on object",
            "solutions": [
                "Verify object has expected method",
                "Check if method was renamed",
                "Consider mocking"
            ]
        },
        "assertion_failure": {
            "symptoms": ["assertionerror", "assert"],
            "description": "Test assertion did not pass",
            "solutions": [
                "Review expected vs actual values",
                "Check test data setup",
                "Verify business logic"
            ]
        },
        "type_error": {
            "symptoms": ["typeerror"],
            "description": "Type mismatch or incorrect usage",
            "solutions": [
                "Check parameter types",
                "Verify return type expectations",
                "Look for None values"
            ]
        }
    }


def generate_storm_commands(test_name: str, test_file_path: str) -> List[str]:
    """
    Generate appropriate Storm test commands for debugging
    
    Args:
        test_name: Name of the failing test
        test_file_path: Path to the test file
        
    Returns:
        List of Storm test commands
    """
    commands = [
        f"./test.sh -k {test_name} -v",
        f"./test.sh -k {test_name.replace('test_', '')} --quick",
        f"./test.sh --failed -v"
    ]
    
    # Add component-specific commands
    if "console" in test_file_path:
        commands.append("./test.sh -k console --quick")
    elif "logger" in test_file_path:
        commands.append("./test.sh -k logger --quick")
    elif "config" in test_file_path:
        commands.append("./test.sh -k config --quick")
    
    return commands


def get_related_tests(test_name: str, test_file_path: str) -> List[str]:
    """
    Get related tests to check for patterns
    
    Args:
        test_name: Name of the failing test
        test_file_path: Path to the test file
        
    Returns:
        List of related test commands
    """
    related = []
    
    # Extract test class if present
    test_class = test_name.split("::")[0] if "::" in test_name else ""
    if test_class:
        related.append(f"./test.sh -k {test_class}")
    
    # Add component-specific related tests
    if "console" in test_file_path:
        related.append("./test.sh -k \"console and table\"")
        related.append("./test.sh -k StormConsole")
    elif "logger" in test_file_path:
        related.append("./test.sh -k \"logger and business\"")
        related.append("./test.sh -k ProfessionalLogger")
    elif "config" in test_file_path:
        related.append("./test.sh -k \"config and django\"")
        related.append("./test.sh -k Configuration")
    
    return related


def get_fix_suggestions(error_category: str, test_file_path: str) -> List[str]:
    """
    Get fix suggestions based on error category
    
    Args:
        error_category: Category of the error
        test_file_path: Path to the test file
        
    Returns:
        List of fix suggestions
    """
    suggestions = {
        "Parameter Order Issue": [
            f"Check method signature in {test_file_path}",
            "Verify parameter order matches the actual method definition",
            "Look for methods that expect (title, columns, rows) vs (columns, rows, title=...)",
            "Check similar tests for correct calling patterns"
        ],
        "Import Error": [
            "Check if required dependencies are installed",
            "Verify import paths in test file",
            "Check for circular imports",
            "Ensure Storm Logger modules are properly packaged"
        ],
        "Attribute Error": [
            "Verify the object has the expected method/property",
            "Check if method was renamed or moved",
            "Look at the class definition for available methods",
            "Consider if mocking is needed for the test"
        ],
        "Assertion Failure": [
            "Review the expected vs actual values",
            "Check if test data setup is correct",
            "Verify business logic implementation",
            "Consider if test expectations need updating"
        ],
        "Type Error": [
            "Check parameter types match method signature",
            "Verify return type expectations",
            "Look for None values where objects expected",
            "Check type annotations in Storm Logger code"
        ]
    }
    
    return suggestions.get(error_category, [
        "Read the full error traceback carefully",
        "Check Storm Logger documentation",
        "Look for similar issues in other tests",
        "Consider creating a minimal reproduction case"
    ])