from __future__ import annotations

import gc
import os
import time

import pytest
from inference.models.qwen3_5vl.qwen3_5vl_inference_models import \
    InferenceModelsQwen35VLAdapter


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 _make_instance_without_init():
    """
    Create an instance of InferenceModelsQwen35VLAdapter without calling its
    potentially heavy __init__ (which would try to load models). We use
    object.__new__ to get a real instance of the class without invoking the
    constructor. This is intentional because map_inference_kwargs is a pure
    method that does not depend on instance initialization.
    """
    return object.__new__(InferenceModelsQwen35VLAdapter)

def test_returns_same_dict_object():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    original = {'a': 1, 'b': 'two'}
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_returns_same_dict_object', 'map_inference_kwargs', '2', codeflash_loop_index, original)
    codeflash_output = codeflash_return_value
    returned = codeflash_output

def test_preserves_mutable_nested_objects_and_is_alias():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    nested_list = [1, 2, 3]
    nested_dict = {'x': 'y'}
    original = {'lst': nested_list, 'd': nested_dict}
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_preserves_mutable_nested_objects_and_is_alias', 'map_inference_kwargs', '4', codeflash_loop_index, original)
    codeflash_output = codeflash_return_value
    returned = codeflash_output
    returned['lst'].append(4)
    returned['d']['z'] = 'new'

def test_handles_empty_dict():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    original = {}
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_handles_empty_dict', 'map_inference_kwargs', '2', codeflash_loop_index, original)
    codeflash_output = codeflash_return_value
    returned = codeflash_output

def test_none_is_returned_unchanged():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_none_is_returned_unchanged', 'map_inference_kwargs', '1', codeflash_loop_index, None)
    codeflash_output = codeflash_return_value
    returned = codeflash_output

def test_non_dict_types_returned_unchanged():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    tup = (1, 2, 3)
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_non_dict_types_returned_unchanged', 'map_inference_kwargs', '2', codeflash_loop_index, tup)
    codeflash_output = codeflash_return_value
    returned_tup = codeflash_output
    s = 'a string'
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_non_dict_types_returned_unchanged', 'map_inference_kwargs', '5', codeflash_loop_index, s)
    codeflash_output = codeflash_return_value
    returned_s = codeflash_output
    n = 42
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_non_dict_types_returned_unchanged', 'map_inference_kwargs', '8', codeflash_loop_index, n)
    codeflash_output = codeflash_return_value
    returned_n = codeflash_output

def test_special_characters_and_unicode_keys_values():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    original = {'newline\nkey': 'value\nwith\nlines', 'unicode_♠': 'emoji_🙂', 'quotes\'"`': '"\'`'}
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_special_characters_and_unicode_keys_values', 'map_inference_kwargs', '2', codeflash_loop_index, original)
    codeflash_output = codeflash_return_value
    returned = codeflash_output
    for k, v in original.items():
        pass

def test_large_dict_identity_and_repeated_calls():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    large = {f'key_{i}': i for i in range(1000)}
    for _ in range(1000):
        codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_large_dict_identity_and_repeated_calls', 'map_inference_kwargs', '2_0', codeflash_loop_index, large)
        codeflash_output = codeflash_return_value
        returned = codeflash_output

def test_large_nested_structure_preserved_and_mutable():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    inst = _make_instance_without_init()
    large_nested = {f'k{i}': [i] for i in range(1000)}
    codeflash_return_value = codeflash_wrap(inst.map_inference_kwargs, 'tests.inference.unit_tests.test_map_inference_kwargs__unit_test_0', None, 'test_large_nested_structure_preserved_and_mutable', 'map_inference_kwargs', '2', codeflash_loop_index, large_nested)
    codeflash_output = codeflash_return_value
    returned = codeflash_output
    returned['k500'].append('added')