from __future__ import annotations

import gc
import inspect
import os
import time
import urllib.parse
from pathlib import Path

import dill as pickle
import pytest
from inference.core.roboflow_api import _url_for_safe_logging


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}######!')
    iteration = os.environ['CODEFLASH_TEST_ITERATION']
    with Path('{codeflash_run_tmp_dir_client_side}', f'test_return_values_{iteration}.bin').open('ab') as f:
        pickled_values = pickle.dumps((args, kwargs, exception)) if exception else pickle.dumps((args, kwargs, return_value))
        _test_name = f"{codeflash_test_module_name}:{(codeflash_test_class_name + '.' if codeflash_test_class_name else '')}{codeflash_test_name}:{codeflash_function_name}:{codeflash_line_id}".encode('ascii')
        f.write(len(_test_name).to_bytes(4, byteorder='big'))
        f.write(_test_name)
        f.write(codeflash_duration.to_bytes(8, byteorder='big'))
        f.write(len(pickled_values).to_bytes(4, byteorder='big'))
        f.write(pickled_values)
        f.write(codeflash_loop_index.to_bytes(8, byteorder='big'))
        f.write(len(invocation_id).to_bytes(4, byteorder='big'))
        f.write(invocation_id.encode('ascii'))
    if exception:
        raise exception
    return return_value

def test_strips_query_and_fragment_basic():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'https://example.com/v1/resource?api_key=secret&x=1#token'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_strips_query_and_fragment_basic', '_url_for_safe_logging', '1', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_preserves_netloc_with_auth_and_port():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'https://user:pass@example.com:8080/secure/path?token=abc&debug=true'
    expected = 'https://user:pass@example.com:8080/secure/path'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_preserves_netloc_with_auth_and_port', '_url_for_safe_logging', '2', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_root_path_and_trailing_slash_behavior():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url_with_slash = 'http://example.com/?a=1'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url_with_slash)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_root_path_and_trailing_slash_behavior', '_url_for_safe_logging', '1', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value
    url_without_slash = 'http://example.com?a=1'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url_without_slash)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_root_path_and_trailing_slash_behavior', '_url_for_safe_logging', '3', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_removes_params_component_semicolon_in_path():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'http://example.com/path;params?x=1#y'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_removes_params_component_semicolon_in_path', '_url_for_safe_logging', '1', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_empty_string_returns_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind('')
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_empty_string_returns_empty_string', '_url_for_safe_logging', '0', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_no_scheme_treated_as_path_preserves_original_path():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'example.com/path?x=1'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_no_scheme_treated_as_path_preserves_original_path', '_url_for_safe_logging', '1', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_none_raises_type_error():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    with pytest.raises(TypeError):
        _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(None)
        _call__bound__arguments.apply_defaults()
        codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_none_raises_type_error', '_url_for_safe_logging', '0_0', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)

def test_multiple_question_marks_in_query_are_ignored():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'https://example.com/path?x=1?y=2#frag'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_multiple_question_marks_in_query_are_ignored', '_url_for_safe_logging', '1', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_preserves_ipv6_and_port_in_netloc():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    url = 'http://[2001:db8::1]:8080/some/path?token=secret'
    expected = 'http://[2001:db8::1]:8080/some/path'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_preserves_ipv6_and_port_in_netloc', '_url_for_safe_logging', '2', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_large_scale_many_urls_loop_1000():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    count = 1000
    for i in range(count):
        url = f'https://example.com/resource/{i}/sub?param={i}&secret=shh{i}#frag{i}'
        expected = f'https://example.com/resource/{i}/sub'
        _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
        _call__bound__arguments.apply_defaults()
        codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_large_scale_many_urls_loop_1000', '_url_for_safe_logging', '1_2', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
        codeflash_output = codeflash_return_value

def test_large_queries_and_long_paths_performance_style():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    long_path = '/' + '/'.join((f'segment{i}' for i in range(200)))
    long_query = '&'.join((f"p{i}={'x' * 50}" for i in range(200)))
    url = f'https://example.com{long_path}?{long_query}#verylongfragment'
    expected = f'https://example.com{long_path}'
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(url)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_large_queries_and_long_paths_performance_style', '_url_for_safe_logging', '4', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value

def test_expected_behavior_matches_manual_urlparse_reconstruction():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    original = 'https://user:pass@example.com:9090/api/v2/resource;param?apikey=secret&other=1#section'
    parsed = urllib.parse.urlparse(original)
    manual_expected = urllib.parse.urlunparse((parsed.scheme, parsed.netloc, parsed.path, '', '', ''))
    _call__bound__arguments = inspect.signature(_url_for_safe_logging).bind(original)
    _call__bound__arguments.apply_defaults()
    codeflash_return_value = codeflash_wrap(_url_for_safe_logging, 'tests.inference.unit_tests.test__url_for_safe_logging__unit_test_0', None, 'test_expected_behavior_matches_manual_urlparse_reconstruction', '_url_for_safe_logging', '3', codeflash_loop_index, *_call__bound__arguments.args, **_call__bound__arguments.kwargs)
    codeflash_output = codeflash_return_value