"""
Tests for OCPP server functionality
"""
import pytest
import asyncio
from src.server import OCPPServer
from src.dispatcher import MessageDispatcher
from src.storage import MemoryStorage
from src.security import SecurityManager, validate_charge_point_id


class TestOCPPServer:
    """Test cases for OCPP server"""
    
    def test_server_initialization(self):
        """Test server can be initialized"""
        server = OCPPServer("localhost", 9000)
        assert server.host == "localhost"
        assert server.port == 9000
        assert server.transport is None


class TestMessageDispatcher:
    """Test cases for message dispatcher"""
    
    @pytest.mark.asyncio
    async def test_register_handler(self):
        """Test handler registration"""
        dispatcher = MessageDispatcher()
        
        async def test_handler(data):
            return {"status": "ok"}
        
        dispatcher.register_handler("test_message", test_handler)
        assert "test_message" in dispatcher.handlers
        
        result = await dispatcher.dispatch("test_message", {"test": "data"})
        assert result == {"status": "ok"}
    
    @pytest.mark.asyncio
    async def test_unknown_message_type(self):
        """Test handling of unknown message types"""
        dispatcher = MessageDispatcher()
        result = await dispatcher.dispatch("unknown", {"test": "data"})
        assert result is None


class TestStorage:
    """Test cases for storage backends"""
    
    @pytest.mark.asyncio
    async def test_memory_storage(self):
        """Test memory storage operations"""
        storage = MemoryStorage()
        
        # Test set and get
        await storage.set("test_key", "test_value")
        value = await storage.get("test_key")
        assert value == "test_value"
        
        # Test exists
        exists = await storage.exists("test_key")
        assert exists is True
        
        # Test delete
        await storage.delete("test_key")
        value = await storage.get("test_key")
        assert value is None
        
        exists = await storage.exists("test_key")
        assert exists is False


class TestSecurity:
    """Test cases for security functionality"""
    
    def test_charge_point_id_validation(self):
        """Test charge point ID validation"""
        # Valid IDs
        assert validate_charge_point_id("CP001") is True
        assert validate_charge_point_id("CP-001") is True
        assert validate_charge_point_id("CP_001") is True
        
        # Invalid IDs
        assert validate_charge_point_id("") is False
        assert validate_charge_point_id("CP@001") is False
        assert validate_charge_point_id("A" * 21) is False  # Too long
    
    def test_security_manager(self):
        """Test security manager functionality"""
        security = SecurityManager()
        
        # Test token creation and validation
        token = security.create_session_token("CP001")
        assert len(token) > 0
        assert security.validate_session_token(token) is True
        
        # Test token revocation
        security.revoke_session_token(token)
        assert security.validate_session_token(token) is False


if __name__ == "__main__":
    pytest.main([__file__])
