from __future__ import annotations

import gc
import hashlib
import os
import time

import pytest
from inference.core.entities.types import WorkspaceID
from inference.core.roboflow_api import _prepare_workflow_response_cache_key


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_with_api_key_and_version():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = 'secret-key'
    workspace = WorkspaceID('workspace-1')
    workflow_id = 'workflow-abc'
    workflow_version = 'v1'
    expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_basic_with_api_key_and_version', '_prepare_workflow_response_cache_key', '5', codeflash_loop_index, api_key, workspace, workflow_id, workflow_version)
    codeflash_output = codeflash_return_value
    result = codeflash_output
    expected = f'workflow_definition:{workspace}:{workflow_id}:workflow_version={workflow_version}:{expected_hash}'

def test_basic_with_none_api_key_and_no_version():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = None
    workspace = WorkspaceID('ws-2')
    workflow_id = 'wf-2'
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_basic_with_none_api_key_and_no_version', '_prepare_workflow_response_cache_key', '3', codeflash_loop_index, api_key, workspace, workflow_id, None)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_empty_strings_and_empty_api_key():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = ''
    workspace = WorkspaceID('')
    workflow_id = ''
    workflow_version = ''
    expected_hash = hashlib.md5(b'').hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_empty_strings_and_empty_api_key', '_prepare_workflow_response_cache_key', '5', codeflash_loop_index, api_key, workspace, workflow_id, workflow_version)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_unicode_and_special_characters_in_api_key():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = 'pässw🔒rd-测试'
    workspace = WorkspaceID('ws-unicode')
    workflow_id = 'wf-unicode'
    expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_unicode_and_special_characters_in_api_key', '_prepare_workflow_response_cache_key', '4', codeflash_loop_index, api_key, workspace, workflow_id, None)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_workspace_id_newtype_instance_is_used_directly():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    ws_value = 'workspace-typed-123'
    workspace = WorkspaceID(ws_value)
    api_key = 'k'
    workflow_id = 'wf-typed'
    expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_workspace_id_newtype_instance_is_used_directly', '_prepare_workflow_response_cache_key', '5', codeflash_loop_index, api_key, workspace, workflow_id, None)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_workflow_version_string_zero_vs_int_zero_behavior():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = 'key-zero'
    workspace = WorkspaceID('ws-z')
    workflow_id = 'wf-z'
    version_string_zero = '0'
    expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_workflow_version_string_zero_vs_int_zero_behavior', '_prepare_workflow_response_cache_key', '5', codeflash_loop_index, api_key, workspace, workflow_id, version_string_zero)
    codeflash_output = codeflash_return_value
    result_str_zero = codeflash_output
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_workflow_version_string_zero_vs_int_zero_behavior', '_prepare_workflow_response_cache_key', '7', codeflash_loop_index, api_key, workspace, workflow_id, 0)
    codeflash_output = codeflash_return_value
    result_int_zero = codeflash_output

def test_long_api_key_and_long_identifiers():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    api_key = 'A' * 5000
    workspace = WorkspaceID('W' * 2000)
    workflow_id = 'F' * 2000
    expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
    codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_long_api_key_and_long_identifiers', '_prepare_workflow_response_cache_key', '4', codeflash_loop_index, api_key, workspace, workflow_id, None)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_large_scale_unique_cache_keys_generation():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    count = 1000
    workspace_base = 'ws-ls'
    api_key_base = 'api-key-'
    workflow_base = 'workflow-'
    generated = []
    for i in range(count):
        api_key = f'{api_key_base}{i % 50}'
        workspace = WorkspaceID(f'{workspace_base}-{i % 10}')
        workflow_id = f'{workflow_base}{i}'
        version = f'ver-{i % 5}'
        codeflash_return_value = codeflash_wrap(_prepare_workflow_response_cache_key, 'tests.inference.unit_tests.test__prepare_workflow_response_cache_key__unit_test_0', None, 'test_large_scale_unique_cache_keys_generation', '_prepare_workflow_response_cache_key', '5_4', codeflash_loop_index, api_key, workspace, workflow_id, version)
        codeflash_output = codeflash_return_value
        key = codeflash_output
        generated.append(key)
    sample_indices = [0, 123, 500, 999]
    for idx in sample_indices:
        api_key = f'{api_key_base}{idx % 50}'
        workspace = WorkspaceID(f'{workspace_base}-{idx % 10}')
        workflow_id = f'{workflow_base}{idx}'
        version = f'ver-{idx % 5}'
        expected_hash = hashlib.md5(api_key.encode('utf-8')).hexdigest()
        expected = f'workflow_definition:{workspace}:{workflow_id}:workflow_version={version}:{expected_hash}'