#!/usr/bin/env python3
"""Tests for the Magic: The Gathering Rules Engine"""

import sys
import os

# Add parent directory to path for importing mtg_rules_engine
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from mtg_rules_engine import (
    ABILITY_WORDS,
    KEYWORD_ACTIONS,
    KEYWORD_ABILITIES,
    get_all_keywords,
    get_keyword_info,
    is_valid_keyword,
    get_keyword_type,
    KeywordValidator,
    RulesEngine,
)


def test_keyword_database():
    """Test the keyword database is properly populated."""
    print("=" * 60)
    print("TEST: Keyword Database")
    print("=" * 60)
    
    # Test ability words
    assert len(ABILITY_WORDS) > 0, "Ability words should not be empty"
    assert "adamant" in ABILITY_WORDS, "adamant should be in ability words"
    print(f"  ✓ {len(ABILITY_WORDS)} ability words loaded")
    
    # Test keyword actions
    assert len(KEYWORD_ACTIONS) > 0, "Keyword actions should not be empty"
    assert "fly" not in KEYWORD_ACTIONS and "flying" in KEYWORD_ABILITIES, "flying should be a keyword ability"
    assert "cast" in KEYWORD_ACTIONS, "cast should be a keyword action"
    assert "destroy" in KEYWORD_ACTIONS, "destroy should be a keyword action"
    print(f"  ✓ {len(KEYWORD_ACTIONS)} keyword actions loaded")
    
    # Test keyword abilities
    assert len(KEYWORD_ABILITIES) > 0, "Keyword abilities should not be empty"
    assert "flying" in KEYWORD_ABILITIES, "flying should be a keyword ability"
    assert "haste" in KEYWORD_ABILITIES, "haste should be a keyword ability"
    assert "deathtouch" in KEYWORD_ABILITIES, "deathtouch should be a keyword ability"
    assert "trample" in KEYWORD_ABILITIES, "trample should be a keyword ability"
    assert "hexproof" in KEYWORD_ABILITIES, "hexproof should be a keyword ability"
    assert "flying" in KEYWORD_ABILITIES, "flying should be a keyword ability"
    print(f"  ✓ {len(KEYWORD_ABILITIES)} keyword abilities loaded")
    
    # Test get_all_keywords
    all_keywords = get_all_keywords()
    assert len(all_keywords) > 0, "get_all_keywords should return keywords"
    print(f"  ✓ {len(all_keywords)} total keywords loaded")
    
    # Test get_keyword_info
    info = get_keyword_info("flying")
    assert info is not None, "get_keyword_info should return info"
    assert "rule" in info, "Keyword info should have 'rule'"
    assert "definition" in info, "Keyword info should have 'definition'"
    print(f"  ✓ Keyword info for 'flying': rule={info['rule'][:40]}...")
    
    # Test get_keyword_type
    type_flying = get_keyword_type("flying")
    assert type_flying == "keyword_ability", f"Expected keyword_ability, got {type_flying}"
    type_cast = get_keyword_type("cast")
    assert type_cast == "keyword_action", f"Expected keyword_action, got {type_cast}"
    print(f"  ✓ Keyword type for 'flying': {type_flying}")
    print(f"  ✓ Keyword type for 'cast': {type_cast}")
    
    print("  ✓ All keyword database tests passed!\n")


def test_keyword_validator():
    """Test the keyword validator."""
    print("=" * 60)
    print("TEST: Keyword Validator")
    print("=" * 60)
    
    validator = KeywordValidator()
    
    # Test is_valid_keyword
    assert validator.is_valid_keyword("flying"), "flying should be valid"
    assert validator.is_valid_keyword("haste"), "haste should be valid"
    assert not validator.is_valid_keyword("notarealkeyword"), "notarealkeyword should be invalid"
    print("  ✓ is_valid_keyword works correctly")
    
    # Test find_keywords_in_text
    text = "Flying creatures can't be blocked except by flying creatures with flying abilities."
    found = validator.find_keywords_in_text(text)
    assert "flying" in found, "flying should be found"
    assert found["flying"] == 3, f"Expected 3 'flying', got {found['flying']}"
    print(f"  ✓ find_keywords_in_text found {found}")
    
    # Test validate_card_text
    card_text = "Flying, trample. Haste. When this creature attacks, it deals extra damage."
    errors = validator.validate_card_text(card_text)
    # No errors expected for valid keywords
    print(f"  ✓ validate_card_text: {len(errors)} errors (expected 0)")
    
    # Test check_for_misspelled_keywords
    misspelled = validator.check_for_misspelled_keywords("I want to fly with this haste creature.")
    # "fly" should suggest "flying"
    print(f"  ✓ check_for_misspelled_keywords found {len(misspelled)} potential misspellings")
    
    # Test export_keywords
    exported = validator.export_keywords()
    assert "total_keywords" in exported, "export_keywords should have total_keywords"
    assert "ability_words" in exported, "export_keywords should have ability_words"
    assert "keyword_actions" in exported, "export_keywords should have keyword_actions"
    assert "keyword_abilities" in exported, "export_keywords should have keyword_abilities"
    print(f"  ✓ export_keywords has all expected fields")
    
    print("  ✓ All keyword validator tests passed!\n")


def test_rules_engine():
    """Test the rules engine."""
    print("=" * 60)
    print("TEST: Rules Engine")
    print("=" * 60)
    
    engine = RulesEngine()
    
    # Test validate_card with a valid creature
    valid_card = {
        "name": "Garruk the Wreathshaper",
        "text": "Flying, trample. When Garruk enters, create a 1/1 green Elf creature token.",
        "type": "CREATURE",
        "power_toughness": (6, 6),
        "color": ["GREEN"],
        "abilities": ["flying", "trample"],
    }
    errors = engine.validate_card(valid_card)
    # Some errors expected (text analysis, etc.)
    print(f"  ✓ validate_card returned {len(errors)} errors")
    
    # Test validate_action with a valid attack
    valid_attack = {
        "type": "attack",
        "attacker": {
            "name": "Garruk the Wreathshaper",
            "type": "CREATURE",
            "power": 6,
            "toughness": 6,
            "abilities": ["flying", "trample"],
        },
        "blocking_creatures": [
            {
                "name": "Garruk the Wreathshaper",
                "type": "CREATURE",
                "power": 6,
                "toughness": 6,
                "abilities": ["flying", "trample"],
            }
        ],
    }
    errors = engine.validate_action(valid_attack)
    # Some errors expected (flying creature can't be blocked)
    print(f"  ✓ validate_action returned {len(errors)} errors")
    
    # Test get_rule_text
    rule = engine.get_rule_text("702.9")
    assert rule is not None, "get_rule_text should return a result"
    print(f"  ✓ get_rule_text returned: {rule[:80]}...")
    
    # Test get_keyword_info_summary
    summary = engine.get_keyword_info_summary("flying")
    assert summary is not None, "get_keyword_info_summary should return a summary"
    assert summary["keyword"] == "flying", "Summary should have correct keyword"
    assert summary["rule"] is not None, "Summary should have rule"
    print(f"  ✓ get_keyword_info_summary works: {summary}")
    
    # Test search_keywords
    results = engine.search_keywords("flying")
    assert len(results) > 0, "search_keywords should find matches"
    print(f"  ✓ search_keywords found {len(results)} matches for 'flying'")
    
    # Test validate_game_state
    valid_state = {
        "players": [
            {
                "name": "Player 1",
                "hand": [],
                "creatures": [],
            },
            {
                "name": "Player 2",
                "hand": [],
                "creatures": [],
            },
        ],
        "zones": {
            "stack": [],
        },
    }
    errors = engine.validate_game_state(valid_state)
    # No errors expected for valid state
    print(f"  ✓ validate_game_state returned {len(errors)} errors")
    
    print("  ✓ All rules engine tests passed!\n")


def test_integration():
    """Integration test with the full pipeline."""
    print("=" * 60)
    print("TEST: Integration")
    print("=" * 60)
    
    # End-to-end test: Create a card, validate it, analyze its keywords
    engine = RulesEngine()
    
    card = {
        "name": "Mighty Hero",
        "text": "Flying, trample, trample over planeswalkers. Haste. When this creature enters, create a 1/1 token.",
        "type": "CREATURE",
        "power_toughness": (4, 4),
        "color": ["RED"],
        "abilities": ["flying", "trample", "haste"],
    }
    
    # Validate card
    errors = engine.validate_card(card)
    print(f"  Card validation: {len(errors)} errors")
    
    # Find keywords in card text
    keywords = engine.validator.find_keywords_in_text(card["text"])
    print(f"  Keywords found in card text: {list(keywords.keys())}")
    
    # Get keyword info for each found keyword
    for keyword in keywords:
        info = engine.get_keyword_info_summary(keyword)
        print(f"    - {keyword}: {info.get('rule', 'N/A')}")
    
    # Validate an attack
    attack = {
        "type": "attack",
        "attacker": {
            "name": "Mighty Hero",
            "type": "CREATURE",
            "power": 4,
            "toughness": 4,
            "abilities": ["flying", "trample"],
        },
        "blocking_creatures": [
            {
                "name": "Opponent's Flying Creature",
                "type": "CREATURE",
                "power": 3,
                "toughness": 3,
                "abilities": ["flying"],
            }
        ],
    }
    
    errors = engine.validate_action(attack)
    print(f"  Attack validation: {len(errors)} errors")
    for error in errors:
        print(f"    - {error['message']}")
    
    print("  ✓ Integration test passed!\n")


if __name__ == "__main__":
    print("\n" + "=" * 60)
    print("Magic: The Gathering Rules Engine - Test Suite")
    print("=" * 60 + "\n")
    
    test_keyword_database()
    test_keyword_validator()
    test_rules_engine()
    test_integration()
    
    print("=" * 60)
    print("ALL TESTS PASSED!")
    print("=" * 60)
