from __future__ import annotations

import gc
import os
import time
from argparse import Namespace

import numpy as np
import pytest
from inference.enterprise.workflows.enterprise_blocks.sinks.event_writer.v1 import \
    _detections_to_v2_instance_segmentations


def codeflash_wrap(codeflash_wrapped, codeflash_test_module_name, codeflash_test_class_name, codeflash_test_name, codeflash_function_name, codeflash_line_id, codeflash_loop_index, *args, **kwargs):
    test_id = f'{codeflash_test_module_name}:{codeflash_test_class_name}:{codeflash_test_name}:{codeflash_line_id}:{codeflash_loop_index}'
    if not hasattr(codeflash_wrap, 'index'):
        codeflash_wrap.index = {}
    if test_id in codeflash_wrap.index:
        codeflash_wrap.index[test_id] += 1
    else:
        codeflash_wrap.index[test_id] = 0
    codeflash_test_index = codeflash_wrap.index[test_id]
    invocation_id = f'{codeflash_line_id}_{codeflash_test_index}'
    test_stdout_tag = f"{codeflash_test_module_name}:{(codeflash_test_class_name + '.' if codeflash_test_class_name else '')}{codeflash_test_name}:{codeflash_function_name}:{codeflash_loop_index}:{invocation_id}"
    print(f'!$######{test_stdout_tag}######$!')
    exception = None
    gc.disable()
    try:
        counter = time.perf_counter_ns()
        return_value = codeflash_wrapped(*args, **kwargs)
        codeflash_duration = time.perf_counter_ns() - counter
    except Exception as e:
        codeflash_duration = time.perf_counter_ns() - counter
        exception = e
    gc.enable()
    print(f'!######{test_stdout_tag}:{codeflash_duration}######!')
    if exception:
        raise exception
    return return_value

def test_none_input_returns_empty_list():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_none_input_returns_empty_list', '_detections_to_v2_instance_segmentations', '0', codeflash_loop_index, None)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_single_detection_with_mask_produces_instance_segmentation():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    mask = np.zeros((40, 40), dtype=np.uint8)
    mask[12:28, 12:28] = 255
    xyxy = np.array([[10, 10, 20, 20]], dtype=float)
    confidence = [0.85]
    data = {'class_name': ['cat']}
    detections = Namespace(xyxy=xyxy, confidence=confidence, data=data, mask=[mask])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_single_detection_with_mask_produces_instance_segmentation', '_detections_to_v2_instance_segmentations', '6', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output
    entry = results[0]
    for pt in entry['points']:
        pass

def test_missing_mask_or_too_few_points_skips_detection():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    xyxy = np.array([[0, 0, 5, 5]], dtype=float)
    confidence = [0.5]
    data = {'class_name': ['box']}
    detections = Namespace(xyxy=xyxy, confidence=confidence, data=data, mask=[None])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_missing_mask_or_too_few_points_skips_detection', '_detections_to_v2_instance_segmentations', '4', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output

def test_all_zero_mask_produces_no_contours_and_skips_entry():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    mask = np.zeros((20, 20), dtype=np.uint8)
    xyxy = np.array([[1, 1, 4, 4]], dtype=float)
    confidence = [1.0]
    data = {'class_name': ['nothing']}
    detections = Namespace(xyxy=xyxy, confidence=confidence, data=data, mask=[mask])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_all_zero_mask_produces_no_contours_and_skips_entry', '_detections_to_v2_instance_segmentations', '5', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output

def test_confidence_none_defaults_to_zero():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    mask = np.zeros((30, 30), dtype=np.uint8)
    mask[5:20, 5:20] = 255
    xyxy = np.array([[5, 5, 20, 20]], dtype=float)
    detections = Namespace(xyxy=xyxy, confidence=None, data={'class_name': ['obj']}, mask=[mask])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_confidence_none_defaults_to_zero', '_detections_to_v2_instance_segmentations', '4', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output

def test_missing_class_name_uses_unknown_label():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    mask = np.zeros((30, 30), dtype=np.uint8)
    mask[5:25, 5:25] = 255
    xyxy = np.array([[0, 0, 10, 10], [1, 1, 11, 11]], dtype=float)
    confidence = [0.1, 0.2]
    data = {'class_name': ['dog']}
    detections = Namespace(xyxy=xyxy, confidence=confidence, data=data, mask=[mask, mask])
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_missing_class_name_uses_unknown_label', '_detections_to_v2_instance_segmentations', '6', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output

def test_invalid_input_is_safely_handled_and_returns_empty_list():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    bad_input = 12345
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_invalid_input_is_safely_handled_and_returns_empty_list', '_detections_to_v2_instance_segmentations', '1', codeflash_loop_index, bad_input)
    codeflash_output = codeflash_return_value
    results = codeflash_output

def test_large_scale_many_detections_with_shared_mask():
    np.random.seed(42)
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    N = 300
    small_mask = np.zeros((8, 8), dtype=np.uint8)
    small_mask[2:6, 2:6] = 255
    xyxy = np.zeros((N, 4), dtype=float)
    for i in range(N):
        xyxy[i] = [1.0 + i % 3, 1.0 + i % 3, 4.0 + i % 3, 4.0 + i % 3]
    confidence = [0.5] * N
    data = {'class_name': ['obj'] * N}
    masks = [small_mask] * N
    detections = Namespace(xyxy=xyxy, confidence=confidence, data=data, mask=masks)
    codeflash_return_value = codeflash_wrap(_detections_to_v2_instance_segmentations, 'tests.inference.unit_tests.test__detections_to_v2_instance_segmentations__unit_test_0', None, 'test_large_scale_many_detections_with_shared_mask', '_detections_to_v2_instance_segmentations', '9', codeflash_loop_index, detections)
    codeflash_output = codeflash_return_value
    results = codeflash_output
    for i in (0, N // 2, N - 1):
        entry = results[i]
        for pt in entry['points']:
            pass