"""Tests for the Key Vault client with focus on input validation."""

import pytest

from kvenv.keyvault import (
    InvalidSecretNameError,
    InvalidVaultNameError,
    validate_secret_name,
    validate_vault_name,
)


class TestValidateVaultName:
    """Tests for vault name validation to prevent injection attacks."""

    def test_valid_simple(self):
        validate_vault_name("myvault")  # Should not raise

    def test_valid_with_hyphen(self):
        validate_vault_name("my-vault")  # Should not raise

    def test_valid_with_numbers(self):
        validate_vault_name("myvault123")  # Should not raise

    def test_valid_min_length(self):
        validate_vault_name("abc")  # 3 chars, should not raise

    def test_valid_max_length(self):
        validate_vault_name("a" + "b" * 23)  # 24 chars, should not raise

    def test_invalid_empty(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("")

    def test_invalid_too_short(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("ab")  # 2 chars

    def test_invalid_too_long(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("a" * 25)  # 25 chars

    def test_invalid_starts_with_number(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("1vault")

    def test_invalid_starts_with_hyphen(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("-vault")

    # Injection attack tests
    def test_injection_semicolon(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault; rm -rf /")

    def test_injection_backtick(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault`whoami`")

    def test_injection_dollar(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault$(whoami)")

    def test_injection_pipe(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault|cat /etc/passwd")

    def test_injection_ampersand(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault&&whoami")

    def test_injection_newline(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault\nwhoami")

    def test_injection_space(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault name")

    def test_injection_quote(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault'")

    def test_injection_double_quote(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name('vault"')

    def test_injection_slash(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault/secret")

    def test_injection_backslash(self):
        with pytest.raises(InvalidVaultNameError):
            validate_vault_name("vault\\secret")


class TestValidateSecretName:
    """Tests for secret name validation to prevent injection attacks."""

    def test_valid_simple(self):
        validate_secret_name("mysecret")  # Should not raise

    def test_valid_with_hyphen(self):
        validate_secret_name("my-secret")  # Should not raise

    def test_valid_with_numbers(self):
        validate_secret_name("secret123")  # Should not raise

    def test_valid_single_char(self):
        validate_secret_name("a")  # 1 char, should not raise

    def test_valid_max_length(self):
        validate_secret_name("a" * 127)  # 127 chars, should not raise

    def test_invalid_empty(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("")

    def test_invalid_too_long(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("a" * 128)  # 128 chars

    # Injection attack tests
    def test_injection_semicolon(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret; rm -rf /")

    def test_injection_backtick(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret`whoami`")

    def test_injection_dollar(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret$(whoami)")

    def test_injection_pipe(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret|cat /etc/passwd")

    def test_injection_ampersand(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret&&whoami")

    def test_injection_newline(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret\nwhoami")

    def test_injection_space(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret name")

    def test_injection_quote(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret'")

    def test_injection_double_quote(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name('secret"')

    def test_injection_slash(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret/path")

    def test_injection_backslash(self):
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret\\path")

    def test_injection_underscore(self):
        # Underscores are NOT valid in Azure secret names
        with pytest.raises(InvalidSecretNameError):
            validate_secret_name("secret_name")
