"""
Test the enhanced custom algorithm upload system.
Tests: ParameterMapper, deep analysis, wrapper generation, local integration.
"""
import os
import sys
import tempfile

# Test 1: Imports
print("=" * 60)
print("Test 1: Module Imports")
print("=" * 60)
from mha_toolbox.custom_algorithm_manager import (
    ParameterMapper, AlgorithmParser, AlgorithmValidator,
    AlgorithmIntegrator, CustomAlgorithmManager
)
print("  All imports successful!")

# Test 2: Direct alias mapping
print("\n" + "=" * 60)
print("Test 2: Direct Alias Mapping")
print("=" * 60)
mapper = ParameterMapper()

test_names = {
    'N': 'population_size',
    'pop_size': 'population_size',
    'T': 'max_iterations',
    'max_iter': 'max_iterations',
    'D': 'dimensions',
    'dim': 'dimensions',
    'f': 'objective_function',
    'lb': 'lower_bound',
    'ub': 'upper_bound',
    'swarm_size': 'population_size',
    'epochs': 'max_iterations',
}

for name, expected in test_names.items():
    result = mapper.suggest_mapping(name)
    status = "PASS" if result == expected else "FAIL"
    print(f"  [{status}] {name:15s} -> {result} (expected: {expected})")

# Test 3: Deep code analysis with ambiguous single-letter variables
print("\n" + "=" * 60)
print("Test 3: Deep Code Analysis")
print("=" * 60)

code_with_single_letters = '''
import numpy as np

class MyOptimizer:
    def __init__(self, A=30, B=100, C=10):
        self.A = A
        self.B = B
        self.C = C
    
    def optimize(self, fitness_func, bounds=None):
        pop = np.random.uniform(-100, 100, (self.A, self.C))
        fitness = np.array([fitness_func(x) for x in pop])
        best = pop[0].copy()
        best_fit = fitness[0]
        history = [best_fit]
        
        for t in range(self.B):
            for i in range(self.A):
                new_pos = pop[i] + np.random.randn(self.C)
                new_fit = fitness_func(new_pos)
                if new_fit < fitness[i]:
                    pop[i] = new_pos
                    fitness[i] = new_fit
                    if new_fit < best_fit:
                        best = new_pos.copy()
                        best_fit = new_fit
            history.append(best_fit)
        
        return best, best_fit, history, None, None
'''

analysis = mapper.deep_analyze_code(code_with_single_letters, ['A', 'B', 'C'])
print(f"  Mapped parameters:")
for param, info in analysis.get('mapped', {}).items():
    print(f"    {param} -> {info['suggested']} (confidence: {info['confidence']}, reason: {info['reason']})")
print(f"  Unmapped: {analysis.get('unmapped', [])}")

# Test 4: Wrapper code generation
print("\n" + "=" * 60)
print("Test 4: Wrapper Code Generation")
print("=" * 60)

wrapper_code = mapper.generate_wrapper_code(
    class_name='MyOptimizer',
    parameter_mapping={
        'A': {'suggested': 'population_size', 'confidence': 'high'},
        'B': {'suggested': 'max_iterations', 'confidence': 'high'},
        'C': {'suggested': 'dimensions', 'confidence': 'medium'}
    },
    original_code=code_with_single_letters,
    contributor_info={
        'author': 'TestUser',
        'email': 'test@example.com',
        'date': '2026-04-02'
    }
)

print(f"  Wrapper generated: {len(wrapper_code)} characters")
print(f"  Contains MyOptimizerWrapped: {'MyOptimizerWrapped' in wrapper_code}")
print(f"  Contains CONTRIBUTOR: {'CONTRIBUTOR' in wrapper_code}")
print(f"  Contains credit: {'Contributed by: TestUser' in wrapper_code}")

# Test 5: Full upload workflow (local-only, no GitHub)
print("\n" + "=" * 60)
print("Test 5: Full Upload Workflow (Local)")
print("=" * 60)

manager = CustomAlgorithmManager()

# Write test algorithm to temp file
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False, dir='.') as f:
    f.write(code_with_single_letters)
    temp_path = f.name

try:
    # Step 1: Process upload
    process_result = manager.process_upload(temp_path)
    print(f"  Process result: success={process_result['success']}, stage={process_result['stage']}")
    if process_result.get('parameter_mapping'):
        pm = process_result['parameter_mapping']
        print(f"  Auto-mapped {len(pm.get('mapped', {}))} params, {len(pm.get('unmapped', []))} unmapped")
    
    if process_result['success']:
        # Step 2: Complete upload with local integration
        complete_result = manager.complete_upload(
            file_path=temp_path,
            parameter_mapping=process_result.get('parameter_mapping', {}).get('mapped', {}),
            contributor_info={
                'author': 'TestContributor',
                'email': 'contributor@test.com'
            },
            category='Swarm Intelligence',
            description='A test custom optimizer'
        )
        
        print(f"  Complete upload: success={complete_result['success']}")
        if complete_result.get('local_integration'):
            li = complete_result['local_integration']
            print(f"  Local integration: success={li.get('success')}")
            if li.get('algorithm_id'):
                print(f"  Algorithm ID: {li['algorithm_id']}")
            if li.get('usage_example'):
                print(f"  Usage example available: Yes")
        
        if complete_result.get('github_submission'):
            gs = complete_result['github_submission']
            print(f"  GitHub submission: success={gs.get('success', False)}")
            if not gs.get('success'):
                print(f"  GitHub note: {gs.get('message', gs.get('error', 'N/A'))}")
        
        # Step 3: Try loading and using the algorithm locally
        print("\n  --- Loading and running locally ---")
        local_algos = manager.list_local_algorithms()
        print(f"  Local algorithms registered: {len(local_algos)}")
        
        if local_algos:
            algo_id = local_algos[0]['id']
            try:
                algo_class = manager.load_local_algorithm(algo_id)
                print(f"  Loaded: {algo_class.__name__}")
                
                # Run it!
                optimizer = algo_class(population_size=10, max_iterations=20, dimensions=5)
                result = optimizer.optimize(
                    objective_function=lambda x: sum(x**2)
                )
                print(f"  Optimization result: best_fitness={result.best_fitness_:.6f}")
                print(f"  Execution time: {result.execution_time_:.4f}s")
                print(f"  SUCCESS: Custom algorithm works locally!")
            except Exception as e:
                print(f"  Error running algorithm: {e}")
                import traceback
                traceback.print_exc()

finally:
    # Cleanup
    if os.path.exists(temp_path):
        os.unlink(temp_path)

# Test 6: Contributor credits
print("\n" + "=" * 60)
print("Test 6: Contributor Credits")
print("=" * 60)
credits = manager.get_contributor_credits()
for credit in credits:
    print(f"  {credit['algorithm_name']} by {credit['author']} ({credit['status']})")

print("\n" + "=" * 60)
print("ALL TESTS COMPLETE")
print("=" * 60)
