"""
Test script to verify lazy proxy behavior for theGrifo1553.

This script verifies that:
1. The proxy does NOT initialize hardware at import time
2. The proxy supports all operations used in production code
3. The mock can still replace sys.modules successfully

Run this before and after changes to verify compatibility.

Usage:
    # Test without hardware (should not fail on import)
    python test_lazy_proxy.py --check-import
    
    # Test that all operations are supported
    python test_lazy_proxy.py --check-api
"""

import sys
import os

# Add test environment paths (same as __init__.py)
LIB_DIR = os.path.join(os.path.dirname(__file__), '..', 'env')
sys.path.insert(0, LIB_DIR)
sys.path.insert(0, os.path.join(LIB_DIR, 'site-packages'))

def test_import_no_hardware():
    """Verify that import does NOT require hardware."""
    print("=" * 80)
    print("TEST 1: Import without hardware initialization")
    print("=" * 80)
    
    # Mock the interpreter module to prevent immediate hardware access
    import types
    import warnings
    warnings.filterwarnings('ignore')  # Suppress warnings during test
    
    # Create minimal mock for interpreter
    mock_interpreter = types.ModuleType('interpreter')
    sys.modules['interpreter'] = mock_interpreter
    
    # Also mock potential missing stdlib modules
    for missing_mod in ['uu']:
        if missing_mod not in sys.modules:
            sys.modules[missing_mod] = types.ModuleType(missing_mod)
    
    # Import should succeed now
    try:
        # Clear any previous imports
        if 'leo_grifo_1553' in sys.modules:
            del sys.modules['leo_grifo_1553']
        if 'leo_grifo_common' in sys.modules:
            del sys.modules['leo_grifo_common']
        if 'leo_grifo_core' in sys.modules:
            del sys.modules['leo_grifo_core']
            
        from leo_grifo_1553 import theGrifo1553
        print("✓ Import successful - no hardware initialization triggered")
        print(f"  theGrifo1553 type: {type(theGrifo1553).__name__}")
        print(f"  theGrifo1553 repr: {repr(theGrifo1553)}")
        
        # Check that instance is not yet initialized
        if hasattr(theGrifo1553, '_instance'):
            if theGrifo1553._instance is None:
                print("✓ Proxy is lazy - real instance not yet created")
                print("  Hardware connection will be made only on first method call")
                success = True
            else:
                print("✗ WARNING: Real instance already created at import!")
                print("  This means hardware connection happens at import time!")
                print("  The lazy loading is NOT working correctly.")
                success = False
        else:
            print("✓ theGrifo1553 does not expose _instance (might be replaced by mock)")
            success = True
        
        # Clean up mocks
        for mod in ['interpreter', 'uu']:
            if mod in sys.modules:
                del sys.modules[mod]
        
        return success
    except ImportError as e:
        print(f"✗ FAIL: Import failed with: {e}")
        print("\n  NOTE: Some dependencies are missing in this Python environment.")
        print("  This test cannot verify lazy loading without all dependencies.")
        print("  Run this test in the production environment with PlatformSimulator.")
        return False
    except Exception as e:
        print(f"✗ FAIL: Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return False


def test_api_compatibility():
    """Verify that proxy supports all operations used in production code."""
    print("\n")
    print("=" * 80)
    print("TEST 2: API compatibility checks (no actual hardware calls)")
    print("=" * 80)
    
    try:
        from leo_grifo_1553 import theGrifo1553
        
        # Check that key methods/attributes exist
        api_methods = ['check', 'get', 'set', 'getInterface', 'run']
        
        print("\nChecking API methods availability (using dir()):")
        available = dir(theGrifo1553)
        
        missing = []
        for method in api_methods:
            if method in available:
                print(f"  ✓ {method} - available")
            else:
                print(f"  ✗ {method} - MISSING")
                missing.append(method)
        
        if missing:
            print(f"\n✗ FAIL: Missing methods: {missing}")
            return False
        
        # Check hasattr (used by mock)
        print("\nChecking hasattr() support:")
        for method in api_methods:
            result = hasattr(theGrifo1553, method)
            if result:
                print(f"  ✓ hasattr(theGrifo1553, '{method}') = True")
            else:
                print(f"  ✗ hasattr(theGrifo1553, '{method}') = False")
        
        # Check truthiness
        print("\nChecking truthiness:")
        if theGrifo1553:
            print("  ✓ bool(theGrifo1553) = True")
        else:
            print("  ✗ bool(theGrifo1553) = False (unexpected)")
        
        # Check passability as parameter (type check)
        print("\nChecking usability as parameter:")
        
        def dummy_function(interface):
            """Dummy function that accepts interface parameter."""
            return interface is not None
        
        result = dummy_function(theGrifo1553)
        if result:
            print("  ✓ Can be passed as parameter")
        else:
            print("  ✗ Cannot be passed as parameter")
        
        print("\n✓ All API compatibility checks passed")
        return True
        
    except Exception as e:
        print(f"\n✗ FAIL: API check failed with: {e}")
        import traceback
        traceback.print_exc()
        return False


def test_mock_compatibility():
    """Verify that mock can replace sys.modules successfully."""
    print("\n")
    print("=" * 80)
    print("TEST 3: Mock replacement compatibility")
    print("=" * 80)
    
    try:
        import types
        
        # Simulate what the mock does
        print("\nSimulating mock module injection...")
        
        # Create fake mock module
        class FakeMockInterface:
            def __init__(self):
                self.is_mock = True
            
            def check(self, *args, **kwargs):
                return True, None, None
            
            def get(self, *args, **kwargs):
                return "mock_value", None
            
            def set(self, *args, **kwargs):
                return True, None
            
            def getInterface(self):
                return self
            
            def run(self, enable):
                pass
        
        # Replace sys.modules (like setup_simulation does)
        mock_leo_grifo_1553 = types.ModuleType('leo_grifo_1553')
        mock_leo_grifo_1553.theGrifo1553 = FakeMockInterface()
        original_module = sys.modules.get('leo_grifo_1553')
        sys.modules['leo_grifo_1553'] = mock_leo_grifo_1553
        
        print("  ✓ Mock module injected into sys.modules")
        
        # Re-import should get mock
        from leo_grifo_1553 import theGrifo1553
        
        print(f"  theGrifo1553 type after mock: {type(theGrifo1553)}")
        
        # Check if it's the mock
        if hasattr(theGrifo1553, 'is_mock') and theGrifo1553.is_mock:
            print("  ✓ Re-import successfully retrieved mock object")
        else:
            print("  ✗ Re-import did NOT get mock (got original)")
        
        # Test mock methods work
        result = theGrifo1553.check("test")
        print(f"  ✓ Mock method call successful: check() returned {result}")
        
        # Restore original module
        if original_module:
            sys.modules['leo_grifo_1553'] = original_module
            print("  ✓ Original module restored")
        
        print("\n✓ Mock compatibility test passed")
        return True
        
    except Exception as e:
        print(f"\n✗ FAIL: Mock compatibility test failed: {e}")
        import traceback
        traceback.print_exc()
        return False


def main():
    """Run all tests based on command line arguments."""
    if len(sys.argv) < 2 or '--check-import' in sys.argv:
        success1 = test_import_no_hardware()
        
        if not success1:
            sys.exit(1)
    
    if len(sys.argv) < 2 or '--check-api' in sys.argv:
        success2 = test_api_compatibility()
        success3 = test_mock_compatibility()
        
        if not (success2 and success3):
            sys.exit(1)
    
    print("\n")
    print("=" * 80)
    print("ALL TESTS PASSED ✓")
    print("=" * 80)
    print("\nThe lazy proxy implementation:")
    print("  ✓ Does not initialize hardware at import time")
    print("  ✓ Supports all API methods used in production code")
    print("  ✓ Is compatible with mock module injection")
    print("\nYou can now safely run:")
    print("  - Production mode: python GRIFO_M_PBIT.py (on target reale)")
    print("  - Simulation mode: python GRIFO_M_PBIT.py --simulate")
    print()


if __name__ == '__main__':
    main()
