from __future__ import annotations

import gc
import os
import time

import pytest
from inference.core.workflows.core_steps.sinks.s3.v1 import deduct_csv_header


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_functionality_simple_rows():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'col1,col2\nrow1a,row1b\nrow2a,row2b'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_basic_functionality_simple_rows', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_preserves_whitespace_and_commas():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'h1,h2\n  a , b  ,c\nx,y'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_preserves_whitespace_and_commas', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_empty_string_returns_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = ''
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_empty_string_returns_empty_string', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_single_line_header_only_returns_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'only_header_line'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_single_line_header_only_returns_empty_string', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_trailing_newline_header_only_returns_empty_string():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'header_with_newline\n'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_trailing_newline_header_only_returns_empty_string', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_preserve_blank_lines_between_rows():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'hdr\n\nrow_after_blank'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_preserve_blank_lines_between_rows', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_crlf_mixed_content_is_handled_predictably():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'h\r\nr1\r\nr2'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_crlf_mixed_content_is_handled_predictably', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_non_string_input_raises_attribute_error():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    with pytest.raises(AttributeError):
        codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_non_string_input_raises_attribute_error', 'deduct_csv_header', '0_0', codeflash_loop_index, None)

def test_bytes_input_raises_type_error():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    b = b'h\nr1'
    with pytest.raises(TypeError):
        codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_bytes_input_raises_type_error', 'deduct_csv_header', '1_0', codeflash_loop_index, b)

def test_large_scale_remove_header_from_many_rows():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    n = 1000
    header = 'col'
    rows = [f'row{i}' for i in range(n)]
    content = header + '\n' + '\n'.join(rows)
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_large_scale_remove_header_from_many_rows', 'deduct_csv_header', '4', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output

def test_large_scale_all_empty_rows_after_header():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    n = 1000
    header = 'h'
    empty_rows = [''] * n
    content = header + '\n' + '\n'.join(empty_rows)
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_large_scale_all_empty_rows_after_header', 'deduct_csv_header', '4', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output
    expected = '\n' * (n - 1)

def test_header_with_commas_and_newlines_in_data_only_first_line_removed():
    codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
    content = 'a,b,c\n1,2,3\n4,5,6'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_header_with_commas_and_newlines_in_data_only_first_line_removed', 'deduct_csv_header', '1', codeflash_loop_index, content)
    codeflash_output = codeflash_return_value
    result = codeflash_output
    content2 = 'hdr\nhdr\nrow'
    codeflash_return_value = codeflash_wrap(deduct_csv_header, 'tests.inference.unit_tests.test_deduct_csv_header__unit_test_0', None, 'test_header_with_commas_and_newlines_in_data_only_first_line_removed', 'deduct_csv_header', '4', codeflash_loop_index, content2)
    codeflash_output = codeflash_return_value
    result2 = codeflash_output