import math

from region import Region


def test_tick_nd_basic():
    r = Region("nd-basic")
    # Ensure ND input edge exists; no attached target layers needed for delivery accounting
    r.bind_input_nd("nd", shape=[2, 3], gain=1.0, epsilon_fire=0.01, layer_indices=[])
    flat = [0.0] * 6

    m = r.tick_nd("nd", flat, [2, 3])
    assert m.get_delivered_events() == 0


def test_tick_image_matches_tick_2d_alias_semantics():
    alias_region = Region("tick-image-alias")
    alias_input_index = alias_region.add_input_layer_2d(1, 1, 1.0, 0.01)
    alias_output_index = alias_region.add_output_layer_2d(1, 1, 0.0)
    alias_region.connect_layers_windowed(
        alias_input_index,
        alias_output_index,
        kernel_h=1,
        kernel_w=1,
        stride_h=1,
        stride_w=1,
        padding="same",
    )
    alias_region.bind_input("pixels", [alias_input_index])

    direct_region = Region("tick-two-d")
    direct_input_index = direct_region.add_input_layer_2d(1, 1, 1.0, 0.01)
    direct_output_index = direct_region.add_output_layer_2d(1, 1, 0.0)
    direct_region.connect_layers_windowed(
        direct_input_index,
        direct_output_index,
        kernel_h=1,
        kernel_w=1,
        stride_h=1,
        stride_w=1,
        padding="same",
    )
    direct_region.bind_input("pixels", [direct_input_index])

    frame = [[1.0]]
    alias_metrics = alias_region.tick_image("pixels", frame)
    direct_metrics = direct_region.tick_2d("pixels", frame)

    assert alias_metrics.delivered_events == direct_metrics.delivered_events
    assert alias_metrics.total_slots == direct_metrics.total_slots
    assert alias_metrics.total_synapses == direct_metrics.total_synapses


def test_compute_spatial_metrics_public_wrapper():
    r = Region("spatial-metrics")
    # simple 2D image with a single active pixel at (0,1)
    img = [
        [0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0],
    ]
    m = r.compute_spatial_metrics(img, prefer_output=False)
    assert m.active_pixels == 1
    assert math.isclose(m.centroid_row, 0.0, rel_tol=0.0, abs_tol=1e-12)
    assert math.isclose(m.centroid_col, 1.0, rel_tol=0.0, abs_tol=1e-12)
    assert m.bbox == (0, 0, 1, 1)
