from __future__ import annotations

import gc
import os
import time

import pytest
from inference.core.workflows.core_steps.common.query_language.introspection.core import \
    _get_property_name_options


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_no_properties_returns_none():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_no_properties_returns_none', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_properties_but_no_property_name_returns_none():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'other': {'enum': ['a']}}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_properties_but_no_property_name_returns_none', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_empty_property_name_schema_returns_none():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {}}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_empty_property_name_schema_returns_none', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_property_name_explicitly_none_returns_none():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': None}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_property_name_explicitly_none_returns_none', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_direct_enum_on_property_schema_is_returned():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'enum': ['alpha', 'beta']}}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_direct_enum_on_property_schema_is_returned', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_ref_to_defs_enum_is_resolved():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Foo'}}}
    defs = {'Foo': {'enum': ['x', 'y', 'z']}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_ref_to_defs_enum_is_resolved', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_ref_precedence_over_local_enum():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Foo', 'enum': ['local1', 'local2']}}}
    defs = {'Foo': {'enum': ['remote1', 'remote2']}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_ref_precedence_over_local_enum', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_missing_ref_uses_local_enum_if_present():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Missing', 'enum': ['only_local']}}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_missing_ref_uses_local_enum_if_present', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_resolved_enum_of_non_strings_preserved():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Nums'}}}
    defs = {'Nums': {'enum': [1, 2, 3]}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_resolved_enum_of_non_strings_preserved', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_resolved_enum_as_tuple_converted_to_list():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Tupled'}}}
    defs = {'Tupled': {'enum': ('a', 'b')}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_resolved_enum_as_tuple_converted_to_list', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_resolved_enum_empty_list_is_returned_empty_list_not_none():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Empty'}}}
    defs = {'Empty': {'enum': []}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_resolved_enum_empty_list_is_returned_empty_list_not_none', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_special_characters_and_unicode_in_enum():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    type_def = {'properties': {'property_name': {'enum': ['spécial', 'space bar', '!@#$%^&*()']}}}
    defs = {}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_special_characters_and_unicode_in_enum', '_get_property_name_options', '2', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value

def test_large_defs_lookup_with_many_definitions():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    defs = {}
    for i in range(1000):
        defs[f'Def{i}'] = {'enum': [f'val{i}_a', f'val{i}_b']}
    target_enum = [f'item_{i}' for i in range(500)]
    defs['Target'] = {'enum': target_enum}
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Target'}}}
    codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_large_defs_lookup_with_many_definitions', '_get_property_name_options', '5', codeflash_loop_index, type_def, defs)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_repeated_calls_do_not_mutate_defs_or_return_value():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    enum_values = [f'x{i}' for i in range(200)]
    defs = {'Stable': {'enum': list(enum_values)}}
    type_def = {'properties': {'property_name': {'$ref': '#/$defs/Stable'}}}
    for _ in range(1000):
        codeflash_return_value = codeflash_wrap(_get_property_name_options, 'tests.inference.unit_tests.test__get_property_name_options__unit_test_0', None, 'test_repeated_calls_do_not_mutate_defs_or_return_value', '_get_property_name_options', '3_0', codeflash_loop_index, type_def, defs)
        codeflash_output = codeflash_return_value
        result = codeflash_output