from __future__ import annotations

import numpy as np

from labelme.utils import shape as shape_module

from .util import get_img_and_data


def test_shapes_to_label() -> None:
    img, data = get_img_and_data()
    label_name_to_value = {}
    for shape in data["shapes"]:
        label_name = shape["label"]
        label_value = len(label_name_to_value)
        label_name_to_value[label_name] = label_value
    cls, _ = shape_module.shapes_to_label(
        img.shape, data["shapes"], label_name_to_value
    )
    assert cls.shape == img.shape[:2]


def test_shape_to_mask() -> None:
    img, data = get_img_and_data()
    for shape in data["shapes"]:
        points = shape["points"]
        mask = shape_module.shape_to_mask(img.shape[:2], points)
        assert mask.shape == img.shape[:2]


def test_shape_to_mask_oriented_rectangle_marks_inside_pixels() -> None:
    # Rect spans x in [0, 10], y in [0, 4]; mask is indexed (row=y, col=x).
    mask = shape_module.shape_to_mask(
        img_shape=(20, 20),
        points=[[0.0, 0.0], [10.0, 0.0], [10.0, 4.0], [0.0, 4.0]],
        shape_type="oriented_rectangle",
    )
    assert mask.dtype == bool
    inside_row, inside_col = 2, 5
    outside_row, outside_col = 15, 15
    assert mask[inside_row, inside_col]
    assert not mask[outside_row, outside_col]


def test_shape_to_mask_rectangle_reversed_coords() -> None:
    img_shape = (100, 100)
    mask_tl_br = shape_module.shape_to_mask(
        img_shape, [[10, 10], [50, 50]], shape_type="rectangle"
    )
    mask_br_tl = shape_module.shape_to_mask(
        img_shape, [[50, 50], [10, 10]], shape_type="rectangle"
    )
    mask_tr_bl = shape_module.shape_to_mask(
        img_shape, [[50, 10], [10, 50]], shape_type="rectangle"
    )
    mask_bl_tr = shape_module.shape_to_mask(
        img_shape, [[10, 50], [50, 10]], shape_type="rectangle"
    )
    assert np.array_equal(mask_tl_br, mask_br_tl)
    assert np.array_equal(mask_tl_br, mask_tr_bl)
    assert np.array_equal(mask_tl_br, mask_bl_tr)
    assert mask_tl_br.sum() > 0
