from __future__ import annotations

import gc
import json
import os
import time

import pytest
import requests
from inference.enterprise.workflows.enterprise_blocks.sinks.event_writer.v1 import \
    _extract_detail


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_response(content_bytes: bytes, encoding: str='utf-8') -> requests.Response:
    """
    Construct a real requests.Response object and set its internal _content and encoding.
    We avoid mocks and use the real Response class so .json() and .text behave naturally.
    """
    resp = requests.Response()
    resp._content = content_bytes
    resp.encoding = encoding
    return resp

def test_extract_detail_returns_detail_when_present_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    payload = {'detail': 'something went wrong'}
    resp = _make_response(json.dumps(payload).encode('utf-8'))
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_returns_detail_when_present_string', '_extract_detail', '2', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_returns_response_text_when_detail_missing():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    payload = {'error': 'not found', 'code': 404}
    resp = _make_response(json.dumps(payload).encode('utf-8'))
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_returns_response_text_when_detail_missing', '_extract_detail', '2', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_converts_non_string_detail_to_str():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    payload = {'detail': {'code': 123, 'info': 'bad'}}
    resp = _make_response(json.dumps(payload).encode('utf-8'))
    expected_detail_obj = resp.json().get('detail')
    expected = str(expected_detail_obj)
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_converts_non_string_detail_to_str', '_extract_detail', '4', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value

def test_extract_detail_handles_null_detail_becoming_String_None():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    payload = {'detail': None}
    resp = _make_response(json.dumps(payload).encode('utf-8'))
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_handles_null_detail_becoming_String_None', '_extract_detail', '2', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_returns_text_when_json_parsing_raises():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    raw_text = 'plain text error body: something broke'
    resp = _make_response(raw_text.encode('utf-8'))
    with pytest.raises(Exception):
        resp.json()
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_returns_text_when_json_parsing_raises', '_extract_detail', '3', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_empty_body_returns_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    resp = _make_response(b'', encoding='utf-8')
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_empty_body_returns_empty_string', '_extract_detail', '1', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_preserves_unicode_and_special_characters():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    detail_value = 'déjà vu ☃️ 🚀'
    payload = {'detail': detail_value}
    resp = _make_response(json.dumps(payload, ensure_ascii=False).encode('utf-8'))
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_preserves_unicode_and_special_characters', '_extract_detail', '3', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_extract_detail_bulk_mixed_responses_performance_and_correctness():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    n = 1000
    responses = []
    expected_results = []
    for i in range(n):
        if i % 2 == 0:
            msg = f'message-{i}'
            payload = {'detail': msg}
            resp = _make_response(json.dumps(payload).encode('utf-8'))
            expected_results.append(msg)
        else:
            raw = f'invalid-body-{i}'
            resp = _make_response(raw.encode('utf-8'))
            expected_results.append(raw)
        responses.append(resp)
    results = [_extract_detail(r) for r in responses]

def test_extract_detail_detail_present_but_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    payload = {'detail': ''}
    resp = _make_response(json.dumps(payload).encode('utf-8'))
    codeflash_return_value = codeflash_wrap(_extract_detail, 'tests.inference.unit_tests.test__extract_detail__unit_test_0', None, 'test_extract_detail_detail_present_but_empty_string', '_extract_detail', '2', codeflash_loop_index, resp)
    codeflash_output = codeflash_return_value
    result = codeflash_output