# Copyright The KiCad Developers
# SPDX-License-Identifier: MIT

"""
Tests for PCB footprint operations.

Covers:
- place_footprint()
- get_footprints()
- Footprint manipulation
"""

from kipy.testing._base import TestResults, MM_TO_NM


def test_pcb_footprints(results: TestResults):
    """Test PCB footprint operations."""
    results.section("PCB Footprints")

    from kipy import KiCad
    from kipy.geometry import Vector2

    kicad = KiCad()
    board = kicad.get_board()

    test_x = 160 * MM_TO_NM
    test_y = 100 * MM_TO_NM

    # Test place_footprint
    fp = None
    try:
        footprints_before = len(board.get_footprints())
        fp = board.place_footprint(
            "Resistor_SMD:R_0805_2012Metric",
            Vector2.from_xy(test_x, test_y),
            reference="R_TEST"
        )
        footprints_after = len(board.get_footprints())

        if footprints_after > footprints_before:
            results.ok("place_footprint", "created")
        else:
            results.fail("place_footprint", "footprint count unchanged")
    except Exception as e:
        if "library" in str(e).lower() or "not found" in str(e).lower():
            results.skip("place_footprint", "library not available")
        else:
            results.fail("place_footprint", str(e))

    # Test place_footprint with rotation
    fp2 = None
    try:
        fp2 = board.place_footprint(
            "Resistor_SMD:R_0805_2012Metric",
            Vector2.from_xy(test_x + 10 * MM_TO_NM, test_y),
            reference="R_TEST2",
            orientation=90
        )
        if fp2:
            results.ok("place_footprint_rotated", "created at 90°")
        else:
            results.fail("place_footprint_rotated", "returned None")
    except Exception as e:
        if "library" in str(e).lower() or "not found" in str(e).lower():
            results.skip("place_footprint_rotated", "library not available")
        else:
            results.fail("place_footprint_rotated", str(e))

    # Test place_footprint with layer (bottom)
    fp3 = None
    try:
        from kipy.proto.board.board_types_pb2 import BoardLayer
        fp3 = board.place_footprint(
            "Resistor_SMD:R_0805_2012Metric",
            Vector2.from_xy(test_x + 20 * MM_TO_NM, test_y),
            reference="R_TEST3",
            layer=BoardLayer.BL_B_Cu
        )
        if fp3:
            results.ok("place_footprint_bottom", "created on B.Cu")
        else:
            results.fail("place_footprint_bottom", "returned None")
    except Exception as e:
        if "library" in str(e).lower() or "not found" in str(e).lower():
            results.skip("place_footprint_bottom", "library not available")
        else:
            results.fail("place_footprint_bottom", str(e))

    # Test footprint position verification
    if fp:
        try:
            actual_x = fp.position.x
            actual_y = fp.position.y

            expected_x_mm = 160.0
            expected_y_mm = 100.0

            actual_x_mm = actual_x / MM_TO_NM
            actual_y_mm = actual_y / MM_TO_NM

            if abs(actual_x_mm - expected_x_mm) < 0.1 and abs(actual_y_mm - expected_y_mm) < 0.1:
                results.ok("footprint_position", f"({actual_x_mm:.1f}mm, {actual_y_mm:.1f}mm)")
            else:
                results.fail("footprint_position", f"expected ({expected_x_mm}mm, {expected_y_mm}mm), got ({actual_x_mm:.1f}mm, {actual_y_mm:.1f}mm)")
        except Exception as e:
            results.fail("footprint_position", str(e))
    else:
        results.skip("footprint_position", "no footprint placed")

    # Test footprint properties
    if fp:
        try:
            ref = getattr(fp, 'reference', None)
            value = getattr(fp, 'value', None)
            results.ok("footprint_properties", f"ref={ref}, value={value}")
        except Exception as e:
            results.fail("footprint_properties", str(e))
    else:
        results.skip("footprint_properties", "no footprint placed")

    # Test get pads from footprint
    if fp:
        try:
            # Get pads for this footprint
            fp_id = fp.id if hasattr(fp, 'id') else None
            if fp_id:
                all_pads = board.get_pads()
                fp_pads = [p for p in all_pads if hasattr(p, 'parent') and p.parent == fp_id]
                results.ok("footprint_pads", f"{len(fp_pads)} pads (via parent match)")
            else:
                # Try alternate method
                pads = board.get_pads()
                results.ok("footprint_pads", f"{len(pads)} total pads on board")
        except Exception as e:
            results.fail("footprint_pads", str(e))
    else:
        results.skip("footprint_pads", "no footprint placed")
