#!/usr/bin/env python3
"""Test zero-copy data generation API"""

import s3dlio
import sys

def test_basic_generation():
    """Test basic data generation"""
    print("=" * 70)
    print("TEST 1: Basic Data Generation (Zero-Copy BytesView)")
    print("=" * 70)
    
    # Generate 1 MiB of data
    size = 1024 * 1024
    data = s3dlio.generate_data(size)
    
    print(f"✓ Generated BytesView object: {type(data)}")
    print(f"✓ Length: {len(data)} bytes")
    
    # Test memoryview for ZERO-COPY access
    view = memoryview(data)
    print(f"✓ Created memoryview: {len(view)} bytes (ZERO COPIES!)")
    print(f"✓ First 16 bytes: {bytes(view[:16]).hex()}")
    
    # Test bytes conversion (this DOES copy)
    data_bytes = bytes(data)
    print(f"✓ Converted to bytes: {len(data_bytes)} bytes (copied)")
    
    print()
    return True

def test_custom_threads():
    """Test data generation with custom thread count"""
    print("=" * 70)
    print("TEST 2: Custom Thread Count")
    print("=" * 70)
    
    size = 2 * 1024 * 1024
    data = s3dlio.generate_data_with_threads(size, threads=4)
    
    print(f"✓ Generated with 4 threads: {len(data)} bytes")
    
    # Verify zero-copy access
    view = memoryview(data)
    print(f"✓ Memoryview access: {len(view)} bytes")
    
    print()
    return True

def test_into_buffer():
    """Test zero-copy write into existing buffer"""
    print("=" * 70)
    print("TEST 3: Zero-Copy Write into Existing Buffer")
    print("=" * 70)
    
    # Pre-allocate buffer
    size = 512 * 1024
    buf = bytearray(size)
    
    print(f"✓ Pre-allocated bytearray: {len(buf)} bytes")
    
    # Generate directly into buffer (zero-copy write!)
    nbytes = s3dlio.generate_into_buffer(buf, dedup=2, compress=3)
    
    print(f"✓ Wrote {nbytes} bytes directly into buffer (ZERO-COPY WRITE!)")
    print(f"✓ First 16 bytes: {bytes(buf[:16]).hex()}")
    
    print()
    return True

def test_utility_functions():
    """Test utility functions"""
    print("=" * 70)
    print("TEST 4: Utility Functions")
    print("=" * 70)
    
    total = s3dlio.py_total_cpus()
    default_threads = s3dlio.py_default_data_gen_threads()
    
    print(f"✓ Total CPUs: {total}")
    print(f"✓ Default threads (50%): {default_threads}")
    print(f"✓ Percentage: {(default_threads / total) * 100:.1f}%")
    
    print()
    return True

def test_dedup_compress():
    """Test deduplication and compression factors"""
    print("=" * 70)
    print("TEST 5: Deduplication and Compression")
    print("=" * 70)
    
    size = 1024 * 1024
    
    # Test different configurations
    configs = [
        (1, 1, "No dedup, incompressible"),
        (2, 1, "2:1 dedup, incompressible"),
        (1, 3, "No dedup, 3:1 compression"),
        (2, 3, "2:1 dedup, 3:1 compression"),
    ]
    
    for dedup, compress, desc in configs:
        data = s3dlio.generate_data(size, dedup=dedup, compress=compress)
        view = memoryview(data)
        print(f"✓ {desc}: {len(view)} bytes")
    
    print()
    return True

def main():
    print("\n" + "=" * 70)
    print("s3dlio Zero-Copy Data Generation Test Suite")
    print("Version: 0.9.34")
    print("=" * 70 + "\n")
    
    tests = [
        ("Basic Generation", test_basic_generation),
        ("Custom Threads", test_custom_threads),
        ("Into Buffer", test_into_buffer),
        ("Utility Functions", test_utility_functions),
        ("Dedup/Compress", test_dedup_compress),
    ]
    
    passed = 0
    failed = 0
    
    for name, test_func in tests:
        try:
            if test_func():
                passed += 1
            else:
                failed += 1
                print(f"✗ {name} FAILED")
        except Exception as e:
            failed += 1
            print(f"✗ {name} FAILED with exception: {e}")
            import traceback
            traceback.print_exc()
    
    print("=" * 70)
    print(f"Test Results: {passed} passed, {failed} failed")
    print("=" * 70)
    
    return 0 if failed == 0 else 1

if __name__ == "__main__":
    sys.exit(main())
