"""Unit tests for Cognito adapter."""

from unittest.mock import MagicMock

from augint_billing_lib.adapters.cognito import CognitoAdapter


class TestCognitoAdapter:
    """Test suite for CognitoAdapter."""

    def test_find_user_by_email_success(self):
        """Test successful user lookup by email."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        cognito_client.list_users.return_value = {
            "Users": [
                {
                    "Username": "user123",
                    "Attributes": [
                        {"Name": "email", "Value": "test@example.com"},
                        {"Name": "sub", "Value": "abc-123-def"},
                    ],
                }
            ]
        }

        # Act
        result = adapter.find_user_by_email("test@example.com")

        # Assert
        assert result == "abc-123-def"
        cognito_client.list_users.assert_called_once_with(
            UserPoolId="us-east-1_test",
            Filter='email = "test@example.com"',
            Limit=1,
        )

    def test_find_user_by_email_not_found(self):
        """Test user lookup when email doesn't exist."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        cognito_client.list_users.return_value = {"Users": []}

        # Act
        result = adapter.find_user_by_email("notfound@example.com")

        # Assert
        assert result is None
        cognito_client.list_users.assert_called_once()

    def test_find_user_by_email_missing_sub(self):
        """Test user lookup when sub attribute is missing."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        cognito_client.list_users.return_value = {
            "Users": [
                {
                    "Username": "user123",
                    "Attributes": [
                        {"Name": "email", "Value": "test@example.com"},
                        # Missing sub attribute
                    ],
                }
            ]
        }

        # Act
        result = adapter.find_user_by_email("test@example.com")

        # Assert
        assert result is None

    def test_list_api_keys_for_user_by_description(self):
        """Test finding API keys with user ID in description."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        paginator = MagicMock()
        apigw_client.get_paginator.return_value = paginator
        paginator.paginate.return_value = [
            {
                "items": [
                    {
                        "id": "key1",
                        "value": "api_key_value_1",
                        "description": "Key for user abc-123-def",
                    },
                    {
                        "id": "key2",
                        "value": "api_key_value_2",
                        "description": "Key for another user",
                    },
                    {
                        "id": "key3",
                        "value": "api_key_value_3",
                        "description": "Another key for abc-123-def",
                    },
                ]
            }
        ]

        # Act
        result = adapter.list_api_keys_for_user("abc-123-def")

        # Assert
        assert result == ["key1", "key3"]
        apigw_client.get_paginator.assert_called_once_with("get_api_keys")

    def test_list_api_keys_for_user_by_tags(self):
        """Test finding API keys with user ID in tags."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        paginator = MagicMock()
        apigw_client.get_paginator.return_value = paginator
        paginator.paginate.return_value = [
            {
                "items": [
                    {
                        "id": "key1",
                        "value": "api_key_value_1",
                        "description": "API key",
                        "tags": {"cognitoUserId": "abc-123-def"},
                    },
                    {
                        "id": "key2",
                        "value": "api_key_value_2",
                        "description": "API key",
                        "tags": {"cognitoUserId": "different-user"},
                    },
                    {
                        "id": "key3",
                        "value": "api_key_value_3",
                        "description": "API key",
                        "tags": {"userId": "abc-123-def"},
                    },
                ]
            }
        ]

        # Act
        result = adapter.list_api_keys_for_user("abc-123-def")

        # Assert
        assert result == ["key1", "key3"]

    def test_list_api_keys_for_user_no_keys(self):
        """Test when user has no API keys."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        paginator = MagicMock()
        apigw_client.get_paginator.return_value = paginator
        paginator.paginate.return_value = [
            {
                "items": [
                    {
                        "id": "key1",
                        "value": "api_key_value_1",
                        "description": "Key for different user",
                    }
                ]
            }
        ]

        # Act
        result = adapter.list_api_keys_for_user("abc-123-def")

        # Assert
        assert result == []

    def test_list_api_keys_pagination(self):
        """Test that pagination works correctly for many API keys."""
        # Arrange
        cognito_client = MagicMock()
        apigw_client = MagicMock()
        adapter = CognitoAdapter(cognito_client, apigw_client, "us-east-1_test")

        paginator = MagicMock()
        apigw_client.get_paginator.return_value = paginator
        paginator.paginate.return_value = [
            {
                "items": [
                    {
                        "id": f"key{i}",
                        "value": f"api_key_value_{i}",
                        "name": "abc-123-def-key",
                    }
                    for i in range(3)
                ]
            },
            {
                "items": [
                    {
                        "id": f"key{i}",
                        "value": f"api_key_value_{i}",
                        "name": "abc-123-def-key",
                    }
                    for i in range(3, 5)
                ]
            },
        ]

        # Act
        result = adapter.list_api_keys_for_user("abc-123-def")

        # Assert
        assert len(result) == 5
        assert result == [f"key{i}" for i in range(5)]
