"""Test pygount determinism with serial and parallel execution."""
import subprocess
import json
from pathlib import Path
import concurrent.futures

test_file = Path('pyucc/core/countings_impl.py')
print(f'Testing: {test_file}')
print(f'File size: {test_file.stat().st_size} bytes')
print()

def run_pygount(run_id):
    """Run pygount once and return results."""
    proc = subprocess.run(['pygount', '--format', 'json', str(test_file)], 
                         capture_output=True, text=True, check=True)
    data = json.loads(proc.stdout)
    if isinstance(data, list):
        item = data[0]
    else:
        item = data['files'][0]
    
    return {
        'id': run_id,
        'lineCount': item.get('lineCount'),
        'sourceCount': item.get('sourceCount'),
        'codeCount': item.get('codeCount'),
        'documentationCount': item.get('documentationCount'),
        'emptyCount': item.get('emptyCount'),
        'language': item.get('language')
    }

# Test serial
print('Serial execution (5 runs):')
serial_results = []
for i in range(5):
    result = run_pygount(i+1)
    serial_results.append(result)
    print(f'  Run {result["id"]}: code={result["codeCount"]}, '
          f'doc={result["documentationCount"]}, empty={result["emptyCount"]}')

# Test parallel
print()
print('Parallel execution (10 runs):')
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    futures = [executor.submit(run_pygount, i+1) for i in range(10)]
    parallel_results = [f.result() for f in futures]

for result in parallel_results:
    print(f'  Run {result["id"]}: code={result["codeCount"]}, '
          f'doc={result["documentationCount"]}, empty={result["emptyCount"]}')

# Check consistency
print()
base = {k: v for k, v in serial_results[0].items() if k != 'id'}
all_serial = all({k: v for k, v in r.items() if k != 'id'} == base for r in serial_results)
all_parallel = all({k: v for k, v in r.items() if k != 'id'} == base for r in parallel_results)

print(f'Serial results consistent: {all_serial}')
print(f'Parallel results consistent: {all_parallel}')
print(f'Serial == Parallel: {all_serial and all_parallel}')

if not (all_serial and all_parallel):
    print()
    print('FOUND INCONSISTENCIES!')
    print('First result:', base)
    if not all_serial:
        print('Serial differences:')
        for r in serial_results:
            r_clean = {k: v for k, v in r.items() if k != 'id'}
            if r_clean != base:
                print(f'  Run {r["id"]}: {r_clean}')
    if not all_parallel:
        print('Parallel differences:')
        for r in parallel_results:
            r_clean = {k: v for k, v in r.items() if k != 'id'}
            if r_clean != base:
                print(f'  Run {r["id"]}: {r_clean}')
