#!/usr/bin/env python3
"""Test batch of API changes for issues #177, #179, #181, #182, #184, #185, #188, #189, #190"""
import sys
import mcrfpy

def test_issue_177_gridpoint_grid_pos():
    """Test GridPoint.grid_pos property returns tuple"""
    print("Testing #177: GridPoint.grid_pos property...")

    texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16)
    grid = mcrfpy.Grid(grid_size=(10, 10), texture=texture, pos=(0, 0), size=(160, 160))

    # Get a grid point
    point = grid.at(3, 5)

    # Test grid_pos property exists and returns tuple
    grid_pos = point.grid_pos
    assert isinstance(grid_pos, tuple), f"grid_pos should be tuple, got {type(grid_pos)}"
    assert len(grid_pos) == 2, f"grid_pos should have 2 elements, got {len(grid_pos)}"
    assert grid_pos == (3, 5), f"grid_pos should be (3, 5), got {grid_pos}"

    # Test another position
    point2 = grid.at(7, 2)
    assert point2.grid_pos == (7, 2), f"grid_pos should be (7, 2), got {point2.grid_pos}"

    print("  PASS: GridPoint.grid_pos works correctly")
    return True

def test_issue_179_181_grid_vectors():
    """Test Grid properties return Vectors instead of tuples"""
    print("Testing #179, #181: Grid Vector returns and grid_w/grid_h rename...")

    texture = mcrfpy.Texture("assets/kenney_tinydungeon.png", 16, 16)
    grid = mcrfpy.Grid(grid_size=(15, 20), texture=texture, pos=(50, 100), size=(240, 320))

    # Test center returns Vector
    center = grid.center
    assert hasattr(center, 'x') and hasattr(center, 'y'), f"center should be Vector, got {type(center)}"

    # Test grid_size returns Vector
    grid_size = grid.grid_size
    assert hasattr(grid_size, 'x') and hasattr(grid_size, 'y'), f"grid_size should be Vector, got {type(grid_size)}"
    assert grid_size.x == 15 and grid_size.y == 20, f"grid_size should be (15, 20), got ({grid_size.x}, {grid_size.y})"

    # Test pos returns Vector
    pos = grid.pos
    assert hasattr(pos, 'x') and hasattr(pos, 'y'), f"pos should be Vector, got {type(pos)}"

    print("  PASS: Grid properties return Vectors correctly")
    return True

def test_issue_182_caption_size():
    """Test Caption read-only size, w, h properties"""
    print("Testing #182: Caption read-only size/w/h properties...")

    font = mcrfpy.Font("assets/JetbrainsMono.ttf")
    caption = mcrfpy.Caption(text="Test Caption", pos=(100, 100), font=font)

    # Test size property
    size = caption.size
    assert hasattr(size, 'x') and hasattr(size, 'y'), f"size should be Vector, got {type(size)}"
    assert size.x > 0, f"width should be positive, got {size.x}"
    assert size.y > 0, f"height should be positive, got {size.y}"

    # Test w property
    w = caption.w
    assert isinstance(w, float), f"w should be float, got {type(w)}"
    assert w > 0, f"w should be positive, got {w}"

    # Test h property
    h = caption.h
    assert isinstance(h, float), f"h should be float, got {type(h)}"
    assert h > 0, f"h should be positive, got {h}"

    # Verify w and h match size
    assert abs(w - size.x) < 0.001, f"w ({w}) should match size.x ({size.x})"
    assert abs(h - size.y) < 0.001, f"h ({h}) should match size.y ({size.y})"

    # Verify read-only
    try:
        caption.size = mcrfpy.Vector(100, 100)
        print("  FAIL: size should be read-only")
        return False
    except AttributeError:
        pass  # Expected

    try:
        caption.w = 100
        print("  FAIL: w should be read-only")
        return False
    except AttributeError:
        pass  # Expected

    try:
        caption.h = 100
        print("  FAIL: h should be read-only")
        return False
    except AttributeError:
        pass  # Expected

    print("  PASS: Caption size/w/h properties work correctly")
    return True

def test_issue_184_189_module_namespace():
    """Test window singleton and hidden internal types"""
    print("Testing #184, #189: window singleton + hide classes...")

    # Test window singleton exists
    assert hasattr(mcrfpy, 'window'), "mcrfpy.window should exist"
    window = mcrfpy.window
    assert window is not None, "window should not be None"

    # Verify window properties
    assert hasattr(window, 'resolution'), "window should have resolution property"

    # Test that internal types are hidden from module namespace
    assert not hasattr(mcrfpy, 'UICollectionIter'), "UICollectionIter should be hidden from module namespace"
    assert not hasattr(mcrfpy, 'UIEntityCollectionIter'), "UIEntityCollectionIter should be hidden from module namespace"

    # But iteration should still work - test UICollection iteration
    scene = mcrfpy.Scene("test_scene")
    ui = scene.children
    ui.append(mcrfpy.Frame(pos=(0,0), size=(50,50)))
    ui.append(mcrfpy.Caption(text="hi", pos=(0,0)))

    count = 0
    for item in ui:
        count += 1
    assert count == 2, f"Should iterate over 2 items, got {count}"

    print("  PASS: window singleton and hidden types work correctly")
    return True

def test_issue_185_188_bounds_vectors():
    """Test bounds returns Vector pair, get_bounds() removed"""
    print("Testing #185, #188: Remove get_bounds(), bounds as Vector pair...")

    frame = mcrfpy.Frame(pos=(50, 100), size=(200, 150))

    # Test bounds returns tuple of Vectors
    bounds = frame.bounds
    assert isinstance(bounds, tuple), f"bounds should be tuple, got {type(bounds)}"
    assert len(bounds) == 2, f"bounds should have 2 elements, got {len(bounds)}"

    pos, size = bounds
    assert hasattr(pos, 'x') and hasattr(pos, 'y'), f"pos should be Vector, got {type(pos)}"
    assert hasattr(size, 'x') and hasattr(size, 'y'), f"size should be Vector, got {type(size)}"

    assert pos.x == 50 and pos.y == 100, f"pos should be (50, 100), got ({pos.x}, {pos.y})"
    assert size.x == 200 and size.y == 150, f"size should be (200, 150), got ({size.x}, {size.y})"

    # Test global_bounds also returns Vector pair
    global_bounds = frame.global_bounds
    assert isinstance(global_bounds, tuple), f"global_bounds should be tuple, got {type(global_bounds)}"
    assert len(global_bounds) == 2, f"global_bounds should have 2 elements"

    # Test get_bounds() method is removed (#185)
    assert not hasattr(frame, 'get_bounds'), "get_bounds() method should be removed"

    print("  PASS: bounds returns Vector pairs, get_bounds() removed")
    return True

def test_issue_190_layer_documentation():
    """Test that layer types have documentation"""
    print("Testing #190: TileLayer/ColorLayer documentation...")

    # Verify layer types exist and have docstrings
    assert hasattr(mcrfpy, 'TileLayer'), "TileLayer should exist"
    assert hasattr(mcrfpy, 'ColorLayer'), "ColorLayer should exist"

    # Check that docstrings exist and contain useful info
    tile_doc = mcrfpy.TileLayer.__doc__
    color_doc = mcrfpy.ColorLayer.__doc__

    assert tile_doc is not None and len(tile_doc) > 50, f"TileLayer should have substantial docstring, got: {tile_doc}"
    assert color_doc is not None and len(color_doc) > 50, f"ColorLayer should have substantial docstring, got: {color_doc}"

    # Check for key documentation elements
    assert "layer" in tile_doc.lower() or "tile" in tile_doc.lower(), "TileLayer doc should mention layer or tile"
    assert "layer" in color_doc.lower() or "color" in color_doc.lower(), "ColorLayer doc should mention layer or color"

    print("  PASS: Layer documentation exists")
    return True

def run_all_tests():
    """Run all tests and report results"""
    print("=" * 60)
    print("API Changes Batch Test - Issues #177, #179, #181, #182, #184, #185, #188, #189, #190")
    print("=" * 60)

    tests = [
        ("Issue #177 GridPoint.grid_pos", test_issue_177_gridpoint_grid_pos),
        ("Issue #179, #181 Grid Vectors", test_issue_179_181_grid_vectors),
        ("Issue #182 Caption size/w/h", test_issue_182_caption_size),
        ("Issue #184, #189 Module namespace", test_issue_184_189_module_namespace),
        ("Issue #185, #188 Bounds Vectors", test_issue_185_188_bounds_vectors),
        ("Issue #190 Layer documentation", test_issue_190_layer_documentation),
    ]

    passed = 0
    failed = 0

    for name, test_func in tests:
        try:
            if test_func():
                passed += 1
            else:
                failed += 1
                print(f"  FAILED: {name}")
        except Exception as e:
            failed += 1
            print(f"  ERROR in {name}: {e}")

    print("=" * 60)
    print(f"Results: {passed} passed, {failed} failed")
    print("=" * 60)

    if failed == 0:
        print("ALL TESTS PASSED")
        sys.exit(0)
    else:
        print("SOME TESTS FAILED")
        sys.exit(1)

# Run tests
run_all_tests()
