"""Tests for input validation utilities."""

import pytest

from ai_org.utils.validators import (
    parse_principal_type,
    sanitize_account_name,
    validate_account_id,
    validate_account_name,
    validate_email,
    validate_ou_id,
    validate_permission_set_name,
    validate_region,
    validate_stackset_name,
)


@pytest.mark.unit
class TestValidateEmail:
    @pytest.mark.parametrize(
        "email",
        ["user@example.com", "test.user@domain.org", "a+b@sub.domain.co.uk"],
    )
    def test_valid(self, email):
        assert validate_email(email) is True

    @pytest.mark.parametrize(
        "email",
        ["", "noatsign", "@no-local.com", "no-domain@", "spaces in@email.com"],
    )
    def test_invalid(self, email):
        assert validate_email(email) is False


@pytest.mark.unit
class TestValidateAccountId:
    @pytest.mark.parametrize("aid", ["123456789012", "000000000000", "999999999999"])
    def test_valid(self, aid):
        assert validate_account_id(aid) is True

    @pytest.mark.parametrize(
        "aid", ["", "12345678901", "1234567890123", "12345678901a", "abcdefghijkl"]
    )
    def test_invalid(self, aid):
        assert validate_account_id(aid) is False


@pytest.mark.unit
class TestValidateOuId:
    @pytest.mark.parametrize("ou_id", ["ou-ab12-cd34ef56", "r-ab12"])
    def test_valid(self, ou_id):
        assert validate_ou_id(ou_id) is True

    @pytest.mark.parametrize("ou_id", ["", "ou-short", "r-toolong1", "invalid", "ou-AB12-cd34ef56"])
    def test_invalid(self, ou_id):
        assert validate_ou_id(ou_id) is False


@pytest.mark.unit
class TestValidateAccountName:
    @pytest.mark.parametrize("name", ["MyAccount", "my-account_1", "Test Account"])
    def test_valid(self, name):
        assert validate_account_name(name) is True

    def test_empty(self):
        assert validate_account_name("") is False

    def test_too_long(self):
        assert validate_account_name("a" * 51) is False

    def test_special_chars(self):
        assert validate_account_name("account@name!") is False

    def test_max_length(self):
        assert validate_account_name("a" * 50) is True


@pytest.mark.unit
class TestValidateRegion:
    @pytest.mark.parametrize("region", ["us-east-1", "eu-west-2", "ap-southeast-1"])
    def test_valid(self, region):
        assert validate_region(region) is True

    @pytest.mark.parametrize("region", ["", "US-EAST-1", "us_east_1", "invalid"])
    def test_invalid(self, region):
        assert validate_region(region) is False


@pytest.mark.unit
class TestValidateStacksetName:
    @pytest.mark.parametrize("name", ["my-stackset", "StackSet1", "a"])
    def test_valid(self, name):
        assert validate_stackset_name(name) is True

    def test_empty(self):
        assert validate_stackset_name("") is False

    def test_too_long(self):
        assert validate_stackset_name("a" * 129) is False

    def test_starts_with_number(self):
        assert validate_stackset_name("1stackset") is False

    def test_max_length(self):
        assert validate_stackset_name("a" * 128) is True


@pytest.mark.unit
class TestValidatePermissionSetName:
    @pytest.mark.parametrize("name", ["AdminAccess", "read-only", "dev_role"])
    def test_valid(self, name):
        assert validate_permission_set_name(name) is True

    def test_empty(self):
        assert validate_permission_set_name("") is False

    def test_too_long(self):
        assert validate_permission_set_name("a" * 33) is False

    def test_max_length(self):
        assert validate_permission_set_name("a" * 32) is True


@pytest.mark.unit
class TestSanitizeAccountName:
    def test_replaces_special_chars(self):
        assert sanitize_account_name("my@account!name") == "my-account-name"

    def test_collapses_multiple_hyphens(self):
        assert sanitize_account_name("my---account") == "my-account"

    def test_collapses_spaces(self):
        assert sanitize_account_name("my   account") == "my-account"

    def test_strips_leading_trailing(self):
        assert sanitize_account_name("--name--") == "name"

    def test_truncates_at_50(self):
        result = sanitize_account_name("a" * 100)
        assert len(result) <= 50

    def test_clean_name_unchanged(self):
        assert sanitize_account_name("clean-name") == "clean-name"


@pytest.mark.unit
class TestParsePrincipalType:
    def test_email_returns_user(self):
        assert parse_principal_type("user@example.com") == "USER"

    def test_group_returns_group(self):
        assert parse_principal_type("Developers") == "GROUP"

    def test_empty_returns_group(self):
        assert parse_principal_type("") == "GROUP"
