#!/usr/bin/env python3
"""Basic test for voice protocol components."""

import sys
from voice_codec import Codec2Wrapper, FSKModem, Codec2Mode

# ANSI colors
RED = "\033[91m"
GREEN = "\033[92m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
RESET = "\033[0m"

def test_codec2():
    """Test Codec2 wrapper."""
    print(f"\n{BLUE}=== Testing Codec2 ==={RESET}")
    
    codec = Codec2Wrapper(Codec2Mode.MODE_1200)
    
    # Create simple test data
    test_samples = [0] * 320  # Silent frame
    
    # Encode
    frame = codec.encode(test_samples)
    if frame:
        print(f"{GREEN}✓ Encoded frame: {len(frame.bits)} bytes{RESET}")
        
        # Decode
        decoded = codec.decode(frame)
        print(f"{GREEN}✓ Decoded: {len(decoded)} samples{RESET}")
    else:
        print(f"{RED}✗ Encoding failed{RESET}")

def test_fsk_modem():
    """Test FSK modem."""
    print(f"\n{BLUE}=== Testing FSK Modem ==={RESET}")
    
    modem = FSKModem()
    
    # Test data
    test_data = b"Hello"
    
    # Modulate
    modulated = modem.modulate(test_data)
    print(f"{GREEN}✓ Modulated {len(test_data)} bytes to {len(modulated)} samples{RESET}")
    
    # Demodulate
    demodulated, confidence = modem.demodulate(modulated)
    
    if demodulated == test_data:
        print(f"{GREEN}✓ Demodulation successful (confidence: {confidence:.1%}){RESET}")
    else:
        print(f"{RED}✗ Demodulation failed{RESET}")
        print(f"  Expected: {test_data}")
        print(f"  Got: {demodulated}")

def test_voice_protocol():
    """Test voice protocol integration."""
    print(f"\n{BLUE}=== Testing Voice Protocol Integration ==={RESET}")
    
    from protocol import IcingProtocol
    import time
    
    # Create protocol instances
    alice = IcingProtocol()
    bob = IcingProtocol()
    
    # Simple key exchange
    alice.set_peer_identity(bob.identity_pubkey.hex())
    bob.set_peer_identity(alice.identity_pubkey.hex())
    
    # Wait for servers
    time.sleep(0.5)
    
    # Connect
    alice.connect_to_peer(bob.local_port)
    time.sleep(0.5)
    
    # Quick key exchange
    alice.send_ping_request(1)
    time.sleep(0.1)
    bob.respond_to_ping(0, 1)
    time.sleep(0.1)
    
    alice.generate_ephemeral_keys()
    bob.generate_ephemeral_keys()
    
    alice.send_handshake()
    time.sleep(0.1)
    
    if bob.inbound_messages:
        for i, msg in enumerate(bob.inbound_messages):
            if msg["type"] == "HANDSHAKE":
                bob.generate_ecdhe(i)
                bob.send_handshake()
                break
    time.sleep(0.1)
    
    if alice.inbound_messages:
        for i, msg in enumerate(alice.inbound_messages):
            if msg["type"] == "HANDSHAKE":
                alice.generate_ecdhe(i)
                break
    
    alice.derive_hkdf()
    bob.derive_hkdf()
    
    # Test voice call
    print(f"\n{YELLOW}Testing voice call setup...{RESET}")
    
    if alice.start_voice_call():
        print(f"{GREEN}✓ Voice call initiated{RESET}")
        time.sleep(0.1)
        
        # Bob accepts
        for i, msg in enumerate(bob.inbound_messages):
            if msg["type"] == "VOICE_START":
                vs = msg["parsed"]
                bob.accept_voice_call(vs.session_id, vs.codec_mode, vs.fec_type)
                print(f"{GREEN}✓ Voice call accepted{RESET}")
                break
                
        time.sleep(0.1)
        
        if alice.voice_session_active and bob.voice_session_active:
            print(f"{GREEN}✓ Voice session established{RESET}")
        else:
            print(f"{RED}✗ Voice session failed{RESET}")
    else:
        print(f"{RED}✗ Failed to start voice call{RESET}")
    
    # Cleanup
    alice.stop()
    bob.stop()

def main():
    """Run all tests."""
    print(f"{BLUE}{'='*50}{RESET}")
    print(f"{BLUE}Voice Protocol Component Tests{RESET}")
    print(f"{BLUE}{'='*50}{RESET}")
    
    try:
        test_codec2()
        test_fsk_modem()
        test_voice_protocol()
        
        print(f"\n{GREEN}All tests completed!{RESET}")
        
    except Exception as e:
        print(f"\n{RED}Test failed: {e}{RESET}")
        import traceback
        traceback.print_exc()
        return 1
    
    return 0

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