"""
Tests for Encryption Service
"""
import pytest
from services.encryption_service import EncryptionService


class TestEncryptionService:
    """Tests for encryption functionality."""

    @pytest.fixture
    def service(self):
        """Create encryption service instance."""
        return EncryptionService()

    def test_verify_key_hash_valid(self, service):
        """Test validating a correctly formatted key hash."""
        # SHA-256 produces 32 bytes = 44 chars in base64 (with padding)
        valid_hash = "sha256:eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHg="  # 32 bytes base64
        assert service.verify_key_hash(valid_hash) is True

    def test_verify_key_hash_invalid_prefix(self, service):
        """Test rejecting hash with wrong prefix."""
        invalid_hash = "md5:dGVzdGtleWhhc2g="
        assert service.verify_key_hash(invalid_hash) is False

    def test_verify_key_hash_empty(self, service):
        """Test rejecting empty hash."""
        assert service.verify_key_hash("") is False
        assert service.verify_key_hash(None) is False

    def test_verify_key_hash_invalid_base64(self, service):
        """Test rejecting invalid base64."""
        invalid_hash = "sha256:not-valid-base64!!!"
        assert service.verify_key_hash(invalid_hash) is False

    def test_encrypt_decrypt_roundtrip(self, service):
        """Test that encryption and decryption work correctly."""
        plaintext = "Notiz zu Max: heute wiederholt gestoert"
        namespace_id = "test-ns-12345678"

        # Encrypt
        encrypted = service.encrypt_content(plaintext, namespace_id)
        assert encrypted.startswith("encrypted:")
        assert encrypted != plaintext

        # Decrypt
        decrypted = service.decrypt_content(encrypted, namespace_id)
        assert decrypted == plaintext

    def test_encrypt_different_namespaces(self, service):
        """Test that different namespaces produce different ciphertexts."""
        plaintext = "Same content"

        encrypted1 = service.encrypt_content(plaintext, "namespace-1")
        encrypted2 = service.encrypt_content(plaintext, "namespace-2")

        assert encrypted1 != encrypted2

    def test_decrypt_wrong_namespace_fails(self, service):
        """Test that decryption with wrong namespace fails."""
        plaintext = "Secret content"
        encrypted = service.encrypt_content(plaintext, "correct-namespace")

        with pytest.raises(Exception):
            service.decrypt_content(encrypted, "wrong-namespace")

    def test_decrypt_unencrypted_content(self, service):
        """Test that unencrypted content is returned as-is."""
        plaintext = "Not encrypted"
        result = service.decrypt_content(plaintext, "any-namespace")
        assert result == plaintext

    def test_register_namespace_key(self, service):
        """Test registering a namespace key hash."""
        valid_hash = "sha256:eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHg="
        assert service.register_namespace_key("test-ns", valid_hash) is True

    def test_register_namespace_key_invalid(self, service):
        """Test registering invalid key hash."""
        invalid_hash = "invalid"
        assert service.register_namespace_key("test-ns", invalid_hash) is False

    def test_generate_key_hash(self):
        """Test key hash generation."""
        key = b"test-key-32-bytes-long-exactly!!"  # 32 bytes
        hash_result = EncryptionService.generate_key_hash(key)
        assert hash_result.startswith("sha256:")
        assert len(hash_result) > 10

    def test_generate_namespace_id(self):
        """Test namespace ID generation."""
        ns_id = EncryptionService.generate_namespace_id()
        assert ns_id.startswith("ns-")
        assert len(ns_id) == 3 + 32  # "ns-" + 32 hex chars

    def test_encryption_special_characters(self, service):
        """Test encryption of content with special characters."""
        plaintext = "Schüler mit Umlauten: äöüß 日本語 🎓"
        namespace_id = "test-ns"

        encrypted = service.encrypt_content(plaintext, namespace_id)
        decrypted = service.decrypt_content(encrypted, namespace_id)

        assert decrypted == plaintext

    def test_encryption_empty_string(self, service):
        """Test encryption of empty string."""
        encrypted = service.encrypt_content("", "test-ns")
        decrypted = service.decrypt_content(encrypted, "test-ns")
        assert decrypted == ""
