from __future__ import annotations

import gc
import os
import shutil
import tempfile
import time
from datetime import datetime
from pathlib import Path
from typing import List

import pytest
from inference.core.managers.inference_models_cache_watchdog import (
    FileInfo, list_files)


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
BYTES_IN_MB = 1024 * 1024
LOCK_POSTFIX = '.lock'

class TestListFilesBasic:
    """Basic tests — Verify fundamental functionality under normal conditions."""

    def test_nonexistent_path_returns_empty_list(self):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a non-existent path returns an empty list.'
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_nonexistent_path_returns_empty_list', 'list_files', '1', codeflash_loop_index, '/nonexistent/path/that/does/not/exist')
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_single_file_returns_file_info(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that passing a single file returns a list with one FileInfo object.'
        test_file = tmp_path / 'test.txt'
        test_file.write_text('Hello World')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_single_file_returns_file_info', 'list_files', '3', codeflash_loop_index, str(test_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_lock_file_returns_empty_list(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a .lock file returns an empty list.'
        lock_file = tmp_path / 'test.lock'
        lock_file.write_text('lock content')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_lock_file_returns_empty_list', 'list_files', '3', codeflash_loop_index, str(lock_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_directory_with_single_file(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a directory with a single file returns list with one FileInfo.'
        test_file = tmp_path / 'file.txt'
        test_file.write_text('content')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_directory_with_single_file', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_directory_with_multiple_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a directory with multiple files returns all files.'
        file1 = tmp_path / 'file1.txt'
        file2 = tmp_path / 'file2.txt'
        file3 = tmp_path / 'file3.txt'
        file1.write_text('content1')
        file2.write_text('content2')
        file3.write_text('content3')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_directory_with_multiple_files', 'list_files', '7', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]

    def test_nested_directories_with_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that nested directories are walked and all files are found.'
        subdir1 = tmp_path / 'subdir1'
        subdir2 = subdir1 / 'subdir2'
        subdir1.mkdir()
        subdir2.mkdir()
        file1 = tmp_path / 'root.txt'
        file2 = subdir1 / 'level1.txt'
        file3 = subdir2 / 'level2.txt'
        file1.write_text('root')
        file2.write_text('level1')
        file3.write_text('level2')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_nested_directories_with_files', 'list_files', '11', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]

    def test_lock_files_excluded_from_results(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that .lock files in directories are excluded from results.'
        regular_file = tmp_path / 'file.txt'
        lock_file = tmp_path / 'file.lock'
        regular_file.write_text('regular')
        lock_file.write_text('lock')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesBasic', 'test_lock_files_excluded_from_results', 'list_files', '5', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

class TestListFilesEdgeCases:
    """Edge tests — Evaluate behavior under extreme or unusual conditions."""

    def test_empty_directory_returns_empty_list(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that an empty directory returns an empty list.'
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_empty_directory_returns_empty_list', 'list_files', '1', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_relative_path_is_converted_to_absolute(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that relative paths are converted to absolute paths in results.'
        original_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            test_file = Path('test.txt')
            test_file.write_text('content')
            codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_relative_path_is_converted_to_absolute', 'list_files', '2_3', codeflash_loop_index, '.')
            codeflash_output = codeflash_return_value
            result = codeflash_output
        finally:
            os.chdir(original_cwd)

    def test_symlink_to_file_is_excluded(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that symbolic links to files are not followed.'
        target_file = tmp_path / 'target.txt'
        target_file.write_text('target content')
        symlink_file = tmp_path / 'symlink.txt'
        try:
            symlink_file.symlink_to(target_file)
        except OSError:
            pytest.skip('Symlinks not supported on this system')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_symlink_to_file_is_excluded', 'list_files', '5', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_symlink_to_directory_is_not_followed(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that symbolic links to directories are not followed.'
        target_dir = tmp_path / 'target_dir'
        target_dir.mkdir()
        target_file = target_dir / 'file.txt'
        target_file.write_text('content')
        symlink_dir = tmp_path / 'symlink_dir'
        try:
            symlink_dir.symlink_to(target_dir)
        except OSError:
            pytest.skip('Symlinks not supported on this system')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_symlink_to_directory_is_not_followed', 'list_files', '7', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_symlink_as_direct_path_returns_empty(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that passing a symlink as the path directly returns empty list.'
        target_file = tmp_path / 'target.txt'
        target_file.write_text('content')
        symlink_file = tmp_path / 'symlink.txt'
        try:
            symlink_file.symlink_to(target_file)
        except OSError:
            pytest.skip('Symlinks not supported on this system')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_symlink_as_direct_path_returns_empty', 'list_files', '5', codeflash_loop_index, str(symlink_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_file_info_size_calculated_correctly(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that file size is correctly converted to MB.'
        test_file = tmp_path / 'test.txt'
        size_bytes = 2 * BYTES_IN_MB
        test_file.write_bytes(b'x' * size_bytes)
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_file_info_size_calculated_correctly', 'list_files', '4', codeflash_loop_index, str(test_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_file_info_modified_time_is_datetime(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that modified_at is a datetime object.'
        test_file = tmp_path / 'test.txt'
        test_file.write_text('content')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_file_info_modified_time_is_datetime', 'list_files', '3', codeflash_loop_index, str(test_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_zero_byte_file(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that zero-byte files are included.'
        empty_file = tmp_path / 'empty.txt'
        empty_file.write_bytes(b'')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_zero_byte_file', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_very_small_file_size_precision(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that very small files maintain size precision.'
        test_file = tmp_path / 'small.txt'
        test_file.write_bytes(b'x')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_very_small_file_size_precision', 'list_files', '3', codeflash_loop_index, str(test_file))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        expected_size = 1 / BYTES_IN_MB

    def test_hidden_files_are_included(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that hidden files (starting with dot) are included.'
        hidden_file = tmp_path / '.hidden'
        hidden_file.write_text('hidden content')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_hidden_files_are_included', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_mixed_files_and_lock_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test directory with mix of regular and lock files.'
        file1 = tmp_path / 'file1.txt'
        lock1 = tmp_path / 'lock1.lock'
        file2 = tmp_path / 'file2.txt'
        lock2 = tmp_path / 'file2.lock'
        file1.write_text('content1')
        lock1.write_text('lock1')
        file2.write_text('content2')
        lock2.write_text('lock2')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_mixed_files_and_lock_files', 'list_files', '9', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]

    def test_deeply_nested_directories(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test deeply nested directory structure.'
        current = tmp_path
        for i in range(5):
            current = current / f'level{i}'
            current.mkdir()
            file = current / f'file{i}.txt'
            file.write_text(f'content{i}')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesEdgeCases', 'test_deeply_nested_directories', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

class TestListFilesLargeScale:
    """Large-scale tests — Assess performance and scalability with realistic data volumes."""

    def test_directory_with_100_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a directory with 100 files returns all files.'
        for i in range(100):
            file = tmp_path / f'file_{i:03d}.txt'
            file.write_text(f'content {i}')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_directory_with_100_files', 'list_files', '2', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]

    def test_directory_with_500_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that a directory with 500 files returns all files.'
        for i in range(500):
            file = tmp_path / f'file_{i:04d}.txt'
            file.write_text(f'content {i}')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_directory_with_500_files', 'list_files', '2', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]

    def test_nested_structure_with_many_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test nested directory structure with many files total.'
        total_files = 0
        for dir_idx in range(5):
            subdir = tmp_path / f'subdir_{dir_idx}'
            subdir.mkdir()
            for file_idx in range(50):
                file = subdir / f'file_{file_idx:03d}.txt'
                file.write_text(f'content dir{dir_idx} file{file_idx}')
                total_files += 1
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_nested_structure_with_many_files', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_large_scale_with_lock_files_mixed(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test large directory with mix of regular and lock files.'
        expected_count = 0
        for i in range(100):
            if i % 5 == 0:
                file = tmp_path / f'file_{i:03d}.lock'
            else:
                file = tmp_path / f'file_{i:03d}.txt'
                expected_count += 1
            file.write_text(f'content {i}')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_large_scale_with_lock_files_mixed', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        for file_info in result:
            pass

    def test_files_with_various_sizes(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test files of various sizes to ensure size calculation works at scale.'
        sizes_kb = [1, 10, 100, 512, 1024, 2048]
        for idx, size_kb in enumerate(sizes_kb):
            file = tmp_path / f'file_{idx}.bin'
            file.write_bytes(b'x' * (size_kb * 1024))
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_files_with_various_sizes', 'list_files', '3', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        size_to_count = {}
        for file_info in result:
            size_to_count[file_info.size_mb] = size_to_count.get(file_info.size_mb, 0) + 1
        for size_kb in sizes_kb:
            expected_mb = size_kb * 1024 / BYTES_IN_MB

    def test_deep_nesting_many_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test deeply nested structure with multiple files at each level.'
        total_expected = 0
        current = tmp_path
        for level in range(3):
            for file_idx in range(30):
                file = current / f'file_l{level}_f{file_idx:02d}.txt'
                file.write_text(f'content level{level} file{file_idx}')
                total_expected += 1
            if level < 2:
                current = current / f'level{level}'
                current.mkdir()
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_deep_nesting_many_files', 'list_files', '4', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output

    def test_all_file_infos_have_required_fields(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that all returned FileInfo objects have all required fields.'
        for i in range(50):
            file = tmp_path / f'file_{i:03d}.txt'
            file.write_text(f'content {i}')
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_all_file_infos_have_required_fields', 'list_files', '2', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        for file_info in result:
            pass

    def test_performance_with_1000_files(self, tmp_path):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        'Test that the function handles 1000 files efficiently.'
        for i in range(1000):
            file = tmp_path / f'file_{i:04d}.txt'
            file.write_text(f'content {i}' * 10)
        codeflash_return_value = codeflash_wrap(list_files, 'tests.inference.unit_tests.test_list_files__unit_test_1', 'TestListFilesLargeScale', 'test_performance_with_1000_files', 'list_files', '2', codeflash_loop_index, str(tmp_path))
        codeflash_output = codeflash_return_value
        result = codeflash_output
        paths = [f.path for f in result]
        for file_info in result:
            pass