"""
Unit tests for Amazon Redshift ODBC connection configuration.

Tests verify that:
1. ODBC drivers are available and can be detected
2. Connection strings are properly formatted
3. IAM credential configuration is handled correctly
4. Driver availability checks work as expected
"""

import pytest

try:
    import pyodbc

    PYODBC_AVAILABLE = True
    # pyodbc is used in tests below when PYODBC_AVAILABLE is True
except ImportError:
    pyodbc = None  # type: ignore
    PYODBC_AVAILABLE = False


class TestRedshiftODBCDriverAvailability:
    """Tests for ODBC driver availability detection."""

    @pytest.mark.skipif(not PYODBC_AVAILABLE, reason="pyodbc is not installed")
    def test_pyodbc_imports_successfully(self):
        """Test that pyodbc can be imported."""
        assert pyodbc is not None

    @pytest.mark.skipif(not PYODBC_AVAILABLE, reason="pyodbc is not installed")
    def test_pyodbc_can_list_drivers(self):
        """
        Test that pyodbc can list available drivers.

        Note: The list may be empty on CI systems (especially Linux) where
        no ODBC drivers are installed. This is expected behavior.
        """
        drivers = pyodbc.drivers()
        # Should return a list or tuple (may be empty on Linux CI without drivers)
        assert isinstance(drivers, (list | tuple))
        # On systems with drivers installed, verify the list contains valid strings
        if len(drivers) > 0:
            assert all(isinstance(driver, str) for driver in drivers)
            assert all(len(driver) > 0 for driver in drivers)

    @pytest.mark.skipif(not PYODBC_AVAILABLE, reason="pyodbc is not installed")
    def test_check_for_redshift_driver(self):
        """
        Test checking for Amazon Redshift ODBC driver.

        Note: This test will pass if the driver is found, but will skip
        with a message if not found (not a failure).
        """
        import pyodbc

        drivers = pyodbc.drivers()
        has_redshift = any("Redshift" in driver for driver in drivers)

        if not has_redshift:
            pytest.skip(
                "Amazon Redshift ODBC driver not installed on this system. "
                "This is expected on systems without Redshift driver."
            )

        # If we get here, driver was found
        assert has_redshift

    @pytest.mark.skipif(not PYODBC_AVAILABLE, reason="pyodbc is not installed")
    def test_check_for_postgresql_driver(self):
        """
        Test checking for PostgreSQL ODBC driver (Redshift-compatible).

        PostgreSQL drivers can be used as fallback for Redshift.
        """
        import pyodbc

        drivers = pyodbc.drivers()
        has_postgresql = any("PostgreSQL" in driver for driver in drivers)

        # Just informational - PostgreSQL driver is optional
        if has_postgresql:
            assert True  # Found PostgreSQL driver
        else:
            pytest.skip("PostgreSQL ODBC driver not found (optional)")


class TestRedshiftConnectionString:
    """Tests for Redshift connection string formatting."""

    def test_basic_connection_string_format(self):
        """Test that connection string has correct format."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )

        # Verify all required components are present
        assert "DRIVER=" in connection_string
        assert "SERVER=" in connection_string
        assert "PORT=" in connection_string
        assert "DATABASE=" in connection_string
        assert "UID=" in connection_string
        assert "PWD=" in connection_string

    def test_connection_string_has_driver_specification(self):
        """Test that driver specification is in connection string."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};SERVER=mock-server.example.com;PORT=5439"
        )
        assert "DRIVER={" in connection_string
        assert "}" in connection_string

    def test_connection_string_uses_standard_port(self):
        """Test that default Redshift port (5439) is used."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )
        assert "PORT=5439" in connection_string

    def test_connection_string_includes_credentials(self):
        """Test that connection string includes username and password."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )
        assert "UID=" in connection_string
        assert "PWD=" in connection_string

    def test_connection_string_format_uses_semicolons(self):
        """Test that connection string uses semicolons as separators."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-server.example.com;PORT=5439;DATABASE=mock_test_db"
        )
        assert connection_string.count(";") >= 3

    @pytest.mark.parametrize(
        "component",
        ["DRIVER=", "SERVER=", "PORT=", "DATABASE=", "UID=", "PWD="],
    )
    def test_connection_string_has_required_components(self, component: str):
        """Test that all required components are present in connection string."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )
        assert component in connection_string


class TestRedshiftIAMConfiguration:
    """Tests for Redshift IAM authentication configuration."""

    def test_iam_config_has_required_fields(self):
        """Test that IAM configuration has all required fields."""
        config = {
            "username": "mock_iam_user",
            "database": "mock_test_database",
            "auth_method": "iam-provisioned-cluster",
            "cluster_id": "mock-test-cluster",
            "region": "us-west-2",
            "access_key_id": "AKIAMOCKTEST12345678",
            "secret_access_key": "mock_secret_key_for_testing_only_xyz",
        }

        required_fields = [
            "username",
            "database",
            "auth_method",
            "cluster_id",
            "region",
            "access_key_id",
            "secret_access_key",
        ]

        for field in required_fields:
            assert field in config, f"Required field '{field}' missing from config"

    def test_iam_auth_method_value(self):
        """Test that auth_method is correctly specified."""
        config = {
            "auth_method": "iam-provisioned-cluster",
        }
        assert config["auth_method"] in [
            "iam-provisioned-cluster",
            "iam-serverless",
            "iam",
        ]

    def test_iam_config_has_cluster_id(self):
        """Test that IAM config includes cluster_id."""
        config = {
            "cluster_id": "migrations-aws",
        }
        assert "cluster_id" in config
        assert isinstance(config["cluster_id"], str)
        assert len(config["cluster_id"]) > 0

    def test_iam_config_has_region(self):
        """Test that IAM config includes AWS region."""
        config = {
            "region": "us-west-2",
        }
        assert "region" in config
        assert isinstance(config["region"], str)
        # Basic AWS region format validation
        assert config["region"].startswith("us-") or config["region"].startswith("eu-")

    def test_iam_config_has_credentials(self):
        """Test that IAM config includes AWS credentials."""
        config = {
            "access_key_id": "AKIA2WY53MH3I5EZGIHE",
            "secret_access_key": "***REDACTED***",
        }
        assert "access_key_id" in config
        assert "secret_access_key" in config
        assert len(config["access_key_id"]) > 0
        assert len(config["secret_access_key"]) > 0

    def test_iam_username_format(self):
        """Test that IAM username is properly formatted."""
        config = {
            "username": "mock_iam_user",
        }
        assert "username" in config
        assert isinstance(config["username"], str)
        assert len(config["username"]) > 0

    def test_iam_database_specified(self):
        """Test that database name is specified in IAM config."""
        config = {
            "database": "mock_test_database",
        }
        assert "database" in config
        assert isinstance(config["database"], str)
        assert len(config["database"]) > 0


class TestRedshiftConnectionIntegration:
    """Integration tests for Redshift connection configuration."""

    def test_connection_string_is_valid_format(self):
        """Test that generated connection string follows ODBC format."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )

        # Should not have trailing semicolon
        assert not connection_string.endswith(";")

        # Should have proper key=value format
        parts = connection_string.split(";")
        for part in parts:
            assert "=" in part, f"Invalid connection string part: {part}"

    def test_connection_string_has_minimum_length(self):
        """Test that connection string is not empty or too short."""
        connection_string = (
            "DRIVER={Amazon Redshift (x64)};"
            "SERVER=mock-cluster.example.com;"
            "PORT=5439;"
            "DATABASE=mock_test_db;"
            "UID=mock_test_user;"
            "PWD=mock_test_password_123"
        )
        # Should be a substantial connection string
        assert len(connection_string) > 100

    def test_redshift_cluster_url_format(self):
        """Test that Redshift cluster URL follows expected format."""
        # Test with realistic-looking format (but obviously fake domain)
        cluster_url = "mock-cluster.abc123.us-west-2.example.com"

        # Should contain example.com (our mock domain)
        assert "example.com" in cluster_url

        # Should have region-like pattern
        assert any(
            region in cluster_url
            for region in ["us-west-2", "us-east-1", "eu-west-1", "abc123"]
        )

    def test_iam_config_complete_structure(self):
        """Test that complete IAM configuration has valid structure."""
        config = {
            "username": "mock_iam_user",
            "database": "mock_test_database",
            "auth_method": "iam-provisioned-cluster",
            "cluster_id": "mock-test-cluster",
            "region": "us-west-2",
            "access_key_id": "AKIAMOCKTEST12345678",
            "secret_access_key": "mock_secret_key_for_testing_only_xyz",
        }

        # All fields should be strings
        for key, value in config.items():
            assert isinstance(value, str), f"{key} should be a string"

        # No empty values
        for key, value in config.items():
            assert len(value) > 0, f"{key} should not be empty"


class TestRedshiftDriverNames:
    """Tests for Redshift ODBC driver naming variations."""

    @pytest.mark.parametrize(
        "driver_name",
        [
            "Amazon Redshift (x64)",
            "Amazon Redshift (x86)",
            "Amazon Redshift ODBC Driver (x64)",
        ],
    )
    def test_common_driver_names(self, driver_name: str):
        """Test that common Redshift driver names are recognized."""
        assert "Redshift" in driver_name
        assert "Amazon" in driver_name

    def test_driver_name_in_connection_string(self):
        """Test that driver name is properly enclosed in braces."""
        driver_spec = "DRIVER={Amazon Redshift (x64)}"
        assert driver_spec.startswith("DRIVER={")
        assert driver_spec.endswith("}")
        assert "Amazon Redshift" in driver_spec
