from __future__ import annotations

import gc
import importlib
import os
import time

import inference.core.workflows.core_steps.models.foundation.clip.v1 as clip_v1_module
import pytest
from inference.core.workflows.core_steps.models.foundation.clip.v1 import \
    CLIP_CACHE_MODEL_IDS
from inference.core.workflows.core_steps.models.foundation.clip_comparison.v2 import \
    BlockManifest


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_basic_returns_list_matching_constant():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    canonical = list(clip_v1_module.CLIP_CACHE_MODEL_IDS)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_basic_returns_list_matching_constant', 'get_required_cache_artifacts', '1', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_return_is_a_separate_copy_and_does_not_mutate_module_constant():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    original_snapshot = list(clip_v1_module.CLIP_CACHE_MODEL_IDS)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_return_is_a_separate_copy_and_does_not_mutate_module_constant', 'get_required_cache_artifacts', '1', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output
    if result:
        result[0] = '__mutated_value__'
    else:
        pass

def test_empty_cache_ids_with_monkeypatch(monkeypatch):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    monkeypatch.setattr(clip_v1_module, 'CLIP_CACHE_MODEL_IDS', (), raising=True)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_empty_cache_ids_with_monkeypatch', 'get_required_cache_artifacts', '1', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_various_element_types_are_preserved(monkeypatch):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    heterogeneous = (1, None, 'string', 3.14)
    monkeypatch.setattr(clip_v1_module, 'CLIP_CACHE_MODEL_IDS', heterogeneous, raising=True)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_various_element_types_are_preserved', 'get_required_cache_artifacts', '2', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_duplicates_and_order_are_preserved(monkeypatch):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    duplicated = ['a', 'a', 'b', 'a']
    monkeypatch.setattr(clip_v1_module, 'CLIP_CACHE_MODEL_IDS', duplicated, raising=True)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_duplicates_and_order_are_preserved', 'get_required_cache_artifacts', '2', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_large_scale_1000_items_monkeypatch(monkeypatch):
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    large_list = [f'model_{i}' for i in range(1000)]
    monkeypatch.setattr(clip_v1_module, 'CLIP_CACHE_MODEL_IDS', large_list, raising=True)
    codeflash_return_value = codeflash_wrap(BlockManifest.get_required_cache_artifacts, 'tests.inference.unit_tests.test_get_required_cache_artifacts__unit_test_0', None, 'test_large_scale_1000_items_monkeypatch', 'get_required_cache_artifacts', '2', codeflash_loop_index)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_module_constant_untouched_after_tests():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    reloaded = importlib.reload(clip_v1_module)
    _ = list(reloaded.CLIP_CACHE_MODEL_IDS)