"""Benchmark tests for filelevel module."""

import tempfile
import time
from pathlib import Path

import pytest

from pytola_system.filelevel.cli import FileLevelConfig, FileProcessor


@pytest.mark.benchmark(group="file_processing")
def test_single_file_processing(benchmark) -> None:
    """Benchmark single file processing."""

    def process_single_file():
        with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as tmp:
            tmp.write(b"test content")
            tmp_path = Path(tmp.name)

        try:
            config = FileLevelConfig()
            processor = FileProcessor(tmp_path, config)
            processor.filestem = tmp_path.stem  # Set the stem manually
            processor.rename(level=2)
            return tmp_path.parent / f"{tmp_path.stem}(INT){tmp_path.suffix}"
        finally:
            tmp_path.unlink(missing_ok=True)

    result = benchmark(process_single_file)
    assert result.exists()


@pytest.mark.benchmark(group="file_processing")
def test_batch_file_processing(benchmark) -> None:
    """Benchmark batch file processing."""

    def process_batch_files():
        files = []
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create 10 test files
            for i in range(10):
                file_path = temp_path / f"document_{i}.txt"
                file_path.write_text(f"content {i}")
                files.append(file_path)

            config = FileLevelConfig()
            processors = []
            for f in files:
                processor = FileProcessor(f, config)
                processor.filestem = f.stem  # Set the stem manually
                processors.append(processor)

            def rename_func(processor):
                processor.rename(level=3)

            # Execute operations synchronously since ParallelRunner no longer exists
            for processor in processors:
                rename_func(processor)

            # Return count of processed files
            return len(list(temp_path.glob("*")))

    result = benchmark(process_batch_files)
    assert result >= 10


@pytest.mark.benchmark(group="configuration")
def test_config_creation(benchmark) -> None:
    """Benchmark configuration object creation."""

    def create_configs():
        configs = []
        for _ in range(100):
            config = FileLevelConfig()
            configs.append(config)
        return len(configs)

    result = benchmark(create_configs)
    assert result == 100


@pytest.mark.benchmark(group="string_processing")
def test_filename_transformation(benchmark) -> None:
    """Benchmark filename transformation operations."""

    def transform_filenames():
        test_cases = [
            "document.txt",
            "report(PUB).pdf",
            "file123(CON).docx",
            "secret(CLA)_backup.txt",
            "normal_file_without_markers.txt",
        ]

        config = FileLevelConfig()
        results = []

        for filename in test_cases:
            stem = Path(filename).stem
            processor = FileProcessor(Path(filename), config)
            processor.filestem = stem  # Set the stem manually

            # Simulate the transformation process
            processor._remove_marks(["PUB", "INT", "CON", "CLA"])
            processor._remove_marks(list("1234567890"))
            processor._add_level_mark(2)
            results.append(processor.filestem)

        return len(results)

    result = benchmark(transform_filenames)
    assert result == 5


@pytest.mark.benchmark(group="parallel_execution")
def test_parallel_runner_performance(benchmark) -> None:
    """Benchmark parallel execution performance."""

    def run_parallel_processing():
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create test files
            files = []
            for i in range(20):
                file_path = temp_path / f"file_{i}.txt"
                file_path.write_text(f"data {i}")
                files.append(file_path)

            config = FileLevelConfig()
            processors = []
            for f in files:
                processor = FileProcessor(f, config)
                processor.filestem = f.stem  # Set the stem manually
                processors.append(processor)

            # Test different worker counts
            results = []
            for workers in [1, 2, 4, 8]:
                start_time = time.perf_counter()

                def dummy_operation(processor):
                    # Simulate some work
                    time.sleep(0.01)
                    processor.filestem = f"processed_{processor.filestem}"

                # Execute operations synchronously since ParallelRunner no longer exists
                for processor in processors:
                    dummy_operation(processor)
                elapsed = time.perf_counter() - start_time
                results.append((workers, elapsed))

            return results

    results = benchmark(run_parallel_processing)
    # Verify we got results for all worker counts
    assert len(results) == 4


@pytest.mark.benchmark(group="memory_usage")
def test_memory_efficiency(benchmark) -> None:
    """Benchmark memory efficiency with large batch processing."""

    def process_large_batch():
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_path = Path(temp_dir)

            # Create 100 small files to test memory usage
            files = []
            for i in range(100):
                file_path = temp_path / f"small_file_{i:03d}.txt"
                file_path.write_text(f"minimal content {i}")
                files.append(file_path)

            config = FileLevelConfig()
            processors = []
            for f in files:
                processor = FileProcessor(f, config)
                processor.filestem = f.stem  # Set the stem manually
                processors.append(processor)

            # Process in smaller batches to monitor memory
            batch_size = 10
            processed_count = 0

            for i in range(0, len(processors), batch_size):
                batch = processors[i : i + batch_size]

                def process_batch_item(processor):
                    processor.rename(level=1)

                # Execute operations synchronously since ParallelRunner no longer exists
                for processor in batch:
                    process_batch_item(processor)
                processed_count += len(batch)

            return processed_count

    result = benchmark(process_large_batch)
    assert result == 100


if __name__ == "__main__":
    pytest.main([__file__, "-v", "--benchmark-only"])
