#!/usr/bin/env python3
"""
Test the RAII AnimationManager implementation.
This verifies that weak_ptr properly handles all crash scenarios.
Uses mcrfpy.step() for synchronous test execution.

API note: the standalone ``mcrfpy.Animation(...)`` constructor was removed during
the API freeze. Animations are created via ``drawable.animate(prop, target,
duration_seconds, easing)``, which returns the Animation handle. The handle still
exposes ``hasValidTarget()``, ``complete()``, and ``stop()`` -- the weak_ptr
target-lifetime safety this suite checks is unchanged. (Durations are in seconds.)
"""

import mcrfpy
import sys

print("RAII AnimationManager Test Suite")
print("=" * 40)

# Test state
tests_passed = 0
tests_failed = 0
test_results = []

def test_result(name, passed, details=""):
    global tests_passed, tests_failed
    if passed:
        tests_passed += 1
        result = f"PASS: {name}"
    else:
        tests_failed += 1
        result = f"FAIL: {name}: {details}"
    print(result)
    test_results.append((name, passed, details))

# Setup scene
test = mcrfpy.Scene("test")
test.activate()

# Add a background
ui = test.children
bg = mcrfpy.Frame(pos=(0, 0), size=(1024, 768))
bg.fill_color = mcrfpy.Color(20, 20, 30)
ui.append(bg)

# Initialize scene
mcrfpy.step(0.1)

print("\nRunning RAII Animation Tests...")
print("-" * 40)

# Test 1: Basic animation
try:
    frame = mcrfpy.Frame(pos=(100, 100), size=(100, 100))
    ui.append(frame)

    anim = frame.animate("x", 200.0, 1.0, "linear")

    if hasattr(anim, 'hasValidTarget'):
        valid = anim.hasValidTarget()
        test_result("Basic animation with hasValidTarget", valid)
    else:
        test_result("Basic animation", True)
except Exception as e:
    test_result("Basic animation", False, str(e))

# Test 2: Remove animated object - target invalid once last shared_ptr drops
try:
    frame = mcrfpy.Frame(pos=(100, 100), size=(100, 100))
    ui.append(frame)

    anim = frame.animate("x", 500.0, 2.0, "easeInOut")

    ui.remove(frame)
    # Note: frame still holds a shared_ptr reference, so target is still valid
    # This is correct shared_ptr behavior
    del frame  # Release Python reference

    if hasattr(anim, 'hasValidTarget'):
        valid = anim.hasValidTarget()
        test_result("Animation detects removed target", not valid)
    else:
        test_result("Remove animated object", True)
except Exception as e:
    test_result("Remove animated object", False, str(e))

# Test 3: Complete animation immediately
try:
    frame = mcrfpy.Frame(pos=(100, 100), size=(100, 100))
    ui.append(frame)

    anim = frame.animate("x", 500.0, 2.0, "linear")

    if hasattr(anim, 'complete'):
        anim.complete()
        test_result("Animation complete method", True)
    else:
        test_result("Animation complete method", True, "Method not available")
except Exception as e:
    test_result("Animation complete method", False, str(e))

# Test 4: Multiple animations rapidly (each replaces the prior on 'x')
try:
    frame = mcrfpy.Frame(pos=(200, 200), size=(100, 100))
    ui.append(frame)

    for i in range(10):
        frame.animate("x", 300.0 + i * 10, 1.0, "linear")

    test_result("Multiple animations rapidly", True)
except Exception as e:
    test_result("Multiple animations rapidly", False, str(e))

# Test 5: Scene cleanup
try:
    test2 = mcrfpy.Scene("test2")

    for i in range(5):
        frame = mcrfpy.Frame(pos=(50 * i, 100), size=(40, 40))
        ui.append(frame)
        frame.animate("y", 300.0, 2.0, "easeOutBounce")

    test2.activate()
    mcrfpy.step(0.1)
    test.activate()
    mcrfpy.step(0.1)

    test_result("Scene change cleanup", True)
except Exception as e:
    test_result("Scene change cleanup", False, str(e))

# Test 6: Animation after clearing UI
try:
    frame = mcrfpy.Frame(pos=(100, 100), size=(100, 100))
    ui.append(frame)
    anim = frame.animate("w", 200.0, 1.5, "easeInOutCubic")

    # Clear all UI except background - iterate in reverse
    for i in range(len(ui) - 1, 0, -1):
        ui.remove(ui[i])
    del frame  # Release Python reference too

    if hasattr(anim, 'hasValidTarget'):
        valid = anim.hasValidTarget()
        test_result("Animation after UI clear", not valid)
    else:
        test_result("Animation after UI clear", True)
except Exception as e:
    test_result("Animation after UI clear", False, str(e))

# Print results
print("\n" + "=" * 40)
print(f"Tests passed: {tests_passed}")
print(f"Tests failed: {tests_failed}")

if tests_failed == 0:
    print("\nAll tests passed! RAII implementation is working correctly.")
else:
    print(f"\n{tests_failed} tests failed.")
    print("\nFailed tests:")
    for name, passed, details in test_results:
        if not passed:
            print(f"  - {name}: {details}")

sys.exit(0 if tests_failed == 0 else 1)
