"""Pytest configuration and shared fixtures for BlackAnt SDK tests.

This conftest.py provides shared fixtures for testing, including:
- Credentials from environment variables (instead of hardcoded)
- BlackAnt client fixtures
- Mock fixtures for unit tests
"""

import os
import pytest
from unittest.mock import MagicMock, Mock


# ==========================================
# CREDENTIALS FIXTURES
# ==========================================

@pytest.fixture
def blackant_test_user():
    """Get BlackAnt test username from environment.

    Returns:
        str: Test username, defaults to "milan.balazs" if not set

    Usage:
        Set environment variable:
        export BLACKANT_TEST_USER=your-username
    """
    return os.getenv("BLACKANT_TEST_USER", "milan.balazs")


@pytest.fixture
def blackant_test_password():
    """Get BlackAnt test password from environment.

    Returns:
        str: Test password from environment or None

    Usage:
        Set environment variable:
        export BLACKANT_TEST_PASSWORD=your-password

    Note:
        Returns None if not set to avoid hardcoded credentials.
        Tests requiring real credentials should skip if None.
    """
    password = os.getenv("BLACKANT_TEST_PASSWORD")
    if not password:
        pytest.skip("BLACKANT_TEST_PASSWORD not set in environment")
    return password


@pytest.fixture
def blackant_credentials(blackant_test_user, blackant_test_password):
    """Provide BlackAnt test credentials as dictionary.

    Returns:
        dict: {"user": str, "password": str}

    Usage in tests:
        def test_something(blackant_credentials):
            client = BlackAntClient(**blackant_credentials)
    """
    return {
        "user": blackant_test_user,
        "password": blackant_test_password,
    }


# ==========================================
# CLIENT FIXTURES
# ==========================================

@pytest.fixture
def blackant_client(blackant_credentials):
    """Create a real BlackAnt client with test credentials.

    Returns:
        BlackAntClient: Configured client instance

    Note:
        This requires actual credentials and will skip if not available.
    """
    from blackant import BlackAntClient
    return BlackAntClient(**blackant_credentials)


@pytest.fixture
def blackant_client_mock():
    """Create a mocked BlackAnt client for unit tests.

    Returns:
        Mock: Mocked BlackAntClient with common methods

    Usage:
        def test_something(blackant_client_mock):
            blackant_client_mock.authenticate.return_value = True
            # ... test code
    """
    mock_client = MagicMock()
    mock_client.authenticate.return_value = True
    mock_client.test_connection.return_value = True
    mock_client.list_services.return_value = []
    mock_client.is_authenticated.return_value = True
    return mock_client


# ==========================================
# AUTH FIXTURES
# ==========================================

@pytest.fixture
def mock_auth():
    """Create a mocked BlackAnt authentication handler.

    Returns:
        Mock: Mocked BlackAntAuth with token storage
    """
    from unittest.mock import Mock
    auth = Mock()
    auth.user = "test_user"
    auth.token_store = Mock()
    auth.token_store.user_token = "test_token_123"
    auth.get_token.return_value = "test_token_123"
    auth.authenticate.return_value = "test_token_123"
    auth.is_authenticated.return_value = True
    return auth


@pytest.fixture
def test_token():
    """Provide a test JWT token.

    Returns:
        str: Dummy JWT token for testing
    """
    return "test_jwt_token_for_unit_tests"


# ==========================================
# DOCKER FIXTURES
# ==========================================

@pytest.fixture
def mock_docker_client():
    """Create a mocked Docker client.

    Returns:
        Mock: Mocked Docker client with common methods
    """
    mock_client = MagicMock()
    mock_client.version.return_value = {"Version": "20.10.0"}
    mock_client.ping.return_value = True
    return mock_client


# ==========================================
# ENVIRONMENT FIXTURES
# ==========================================

@pytest.fixture
def test_env_vars(monkeypatch):
    """Set up test environment variables.

    This fixture sets safe default environment variables for testing.

    Usage:
        def test_something(test_env_vars):
            # Environment variables are now set
            assert os.getenv("BLACKANT_BASE_URL") is not None
    """
    test_vars = {
        "BLACKANT_BASE_URL": "https://dev.blackant.app",
        "BLACKANT_LOGIN_URL": "https://dev.blackant.app/api/auth/login",
        "DOCKER_REGISTRY_URL": "env.blackant.app",
        "DOCKER_REGISTRY_NAMESPACE": "systemdevelopers",
        "DOCKER_USE_NGINX_PROXY": "true",
    }

    for key, value in test_vars.items():
        monkeypatch.setenv(key, value)

    return test_vars


# ==========================================
# SKIP MARKERS
# ==========================================

def pytest_configure(config):
    """Register custom pytest markers."""
    config.addinivalue_line(
        "markers",
        "integration: marks tests as integration tests (require real services)"
    )
    config.addinivalue_line(
        "markers",
        "e2e: marks tests as end-to-end tests (require full environment)"
    )
    config.addinivalue_line(
        "markers",
        "requires_credentials: marks tests that require real BlackAnt credentials"
    )


def pytest_collection_modifyitems(config, items):
    """Automatically skip tests requiring credentials if not available."""
    if not os.getenv("BLACKANT_TEST_PASSWORD"):
        skip_creds = pytest.mark.skip(reason="BLACKANT_TEST_PASSWORD not set")
        for item in items:
            if "requires_credentials" in item.keywords:
                item.add_marker(skip_creds)


# ==========================================
# EXAMPLE USAGE IN TESTS
# ==========================================

"""
Example test file using these fixtures:

# test/unit/test_example.py
def test_with_mock_client(blackant_client_mock):
    # Use mocked client for unit tests
    result = blackant_client_mock.authenticate()
    assert result is True

# test/function/test_integration.py
@pytest.mark.requires_credentials
def test_with_real_client(blackant_client):
    # Use real client with credentials from environment
    assert blackant_client.authenticate()

def test_with_credentials_dict(blackant_credentials):
    # Create client manually with credentials
    from blackant import BlackAntClient
    client = BlackAntClient(**blackant_credentials)
    assert client is not None
"""
