"""
Coverage tests for aes_gcm.py - untested branches.
"""

import pytest

# Constants for skip messages
SKIP_AES_GCM = "AES-GCM not available"


# ========================================================================
# AES-GCM encryption branches
# ========================================================================


def test_aes_gcm_encrypt_empty():
    """Test AES-GCM encryption with empty data."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 32  # 256-bit key
        encrypted = encrypt(b"", key)
        assert isinstance(encrypted, bytes)
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_encrypt_small():
    """Test AES-GCM encryption with small data."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 32
        encrypted = encrypt(b"test", key)
        assert isinstance(encrypted, bytes)
        assert len(encrypted) > 0
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_encrypt_large():
    """Test AES-GCM encryption with large data."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 32
        data = b"x" * 10000
        encrypted = encrypt(data, key)
        assert isinstance(encrypted, bytes)
        assert len(encrypted) > len(data)
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


# ========================================================================
# AES-GCM decryption branches
# ========================================================================


def test_aes_gcm_decrypt_valid():
    """Test AES-GCM decryption with valid data."""
    try:
        from bsv.aes_gcm import decrypt, encrypt

        key = b"\x00" * 32
        data = b"test message"

        encrypted = encrypt(data, key)
        decrypted = decrypt(encrypted, key)

        assert decrypted == data
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_decrypt_wrong_key():
    """Test AES-GCM decryption with wrong key."""
    try:
        from bsv.aes_gcm import decrypt, encrypt

        key1 = b"\x00" * 32
        key2 = b"\x01" * 32
        data = b"test"

        encrypted = encrypt(data, key1)
        # Should fail authentication with wrong key
        with pytest.raises(Exception):
            decrypt(encrypted, key2)
            # Expected to fail
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_decrypt_invalid_data():
    """Test AES-GCM decryption with invalid data."""
    try:
        from bsv.aes_gcm import decrypt

        key = b"\x00" * 32

        try:
            decrypt(b"invalid", key)
        except Exception:
            # Expected to fail
            pass
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


# ========================================================================
# Key size branches
# ========================================================================


def test_aes_gcm_128_bit_key():
    """Test AES-GCM with 128-bit key."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 16  # 128-bit
        encrypted = encrypt(b"test", key)
        assert isinstance(encrypted, bytes)
    except (ImportError, ValueError):
        pytest.skip("128-bit AES-GCM not available or not supported")


def test_aes_gcm_256_bit_key():
    """Test AES-GCM with 256-bit key."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 32  # 256-bit
        encrypted = encrypt(b"test", key)
        assert isinstance(encrypted, bytes)
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_invalid_key_size():
    """Test AES-GCM with invalid key size."""
    try:
        from bsv.aes_gcm import encrypt

        key = b"\x00" * 15  # Invalid size

        try:
            encrypt(b"test", key)
        except ValueError:
            # Expected to fail
            pass
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


# ========================================================================
# Edge cases
# ========================================================================


def test_aes_gcm_roundtrip():
    """Test AES-GCM encryption/decryption roundtrip."""
    try:
        from bsv.aes_gcm import decrypt, encrypt

        key = b"\x01\x02\x03" * 10 + b"\x00\x00"  # 32 bytes
        original = b"roundtrip test data"

        encrypted = encrypt(original, key)
        decrypted = decrypt(encrypted, key)

        assert decrypted == original
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_aes_gcm_different_keys_different_output():
    """Test that different keys produce different ciphertext."""
    try:
        from bsv.aes_gcm import encrypt

        key1 = b"\x00" * 32
        key2 = b"\x01" * 32
        data = b"test"

        enc1 = encrypt(data, key1)
        enc2 = encrypt(data, key2)

        assert enc1 != enc2
    except ImportError:
        pytest.skip(SKIP_AES_GCM)


# ========================================================================
# Missing coverage branches (lines 19-20, 59)
# ========================================================================


def test_aes_gcm_decrypt_verification_failure():
    """Test AES-GCM decryption with corrupted data to trigger AESGCMError."""
    try:
        from bsv.aes_gcm import AESGCMError, aes_gcm_decrypt

        key = b"\x00" * 32
        iv = b"\x01" * 16
        aad = b"test"

        # Encrypt valid data
        from bsv.aes_gcm import aes_gcm_encrypt

        plaintext = b"test message"
        ciphertext, tag = aes_gcm_encrypt(plaintext, key, iv, aad)

        # Corrupt the ciphertext to trigger verification failure
        corrupted_ciphertext = ciphertext[:-1] + bytes([ciphertext[-1] ^ 0x01])

        # This should raise AESGCMError
        with pytest.raises(AESGCMError, match="decryption failed"):
            aes_gcm_decrypt(corrupted_ciphertext, key, iv, tag, aad)

    except ImportError:
        pytest.skip(SKIP_AES_GCM)


def test_ghash_padding_block():
    """Test GHASH with input that requires padding (covers line 59)."""
    try:
        from bsv.aes_gcm import ghash

        # Use input that's not a multiple of 16 bytes to trigger padding
        input_bytes = b"hello world"  # 11 bytes, not multiple of 16
        hash_subkey = b"\x00" * 16

        result = ghash(input_bytes, hash_subkey)
        assert len(result) == 16  # GHASH always returns 16 bytes
        assert isinstance(result, bytes)

    except ImportError:
        pytest.skip(SKIP_AES_GCM)
