"""Pytest configuration and fixtures for GQLDB tests."""

import pytest

from gqldb.config import ConfigBuilder, GqldbConfig
from gqldb.client import GqldbClient
from gqldb.errors import GqldbError


# Test database configuration
AUTH_HOST = "192.168.1.104:60061"      # Server with authentication
NO_AUTH_HOST = "192.168.1.104:60062"   # Server without authentication
TEST_HOST = AUTH_HOST                  # Default to auth server
TEST_USERNAME = "admin"
TEST_PASSWORD = "root11"
TEST_DATABASE = "miniCircle"

# Flag to track if authentication is enabled on the server
AUTH_ENABLED = None


def check_auth_enabled(client: GqldbClient) -> bool:
    """Check if authentication is enabled on the server."""
    global AUTH_ENABLED
    if AUTH_ENABLED is not None:
        return AUTH_ENABLED

    try:
        client.login(TEST_USERNAME, TEST_PASSWORD)
        client.logout()
        AUTH_ENABLED = True
    except GqldbError as e:
        if "authentication is not enabled" in str(e).lower():
            AUTH_ENABLED = False
        else:
            # Some other error, assume auth is enabled
            AUTH_ENABLED = True
    return AUTH_ENABLED


def drop_test_graph(client: GqldbClient, graph_name: str) -> None:
    """Drop a test graph safely. Switches to miniCircle first."""
    try:
        client.use_graph(TEST_DATABASE)
    except Exception:
        pass
    try:
        client.drop_graph(graph_name, if_exists=True)
    except Exception:
        pass


def cleanup_test_graphs(client: GqldbClient) -> None:
    """Clean up leftover test graphs to avoid hitting 3-graph limit."""
    try:
        graphs = client.list_graphs()
        for g in graphs:
            if g.name.startswith("test_"):
                print(f"Cleaning up leftover test graph: {g.name}")
                drop_test_graph(client, g.name)
    except Exception:
        pass


@pytest.fixture
def test_config() -> GqldbConfig:
    """Return test configuration."""
    return (
        ConfigBuilder()
        .hosts(TEST_HOST)
        .username(TEST_USERNAME)
        .password(TEST_PASSWORD)
        .default_graph(TEST_DATABASE)
        .timeout(30)
        .build()
    )


@pytest.fixture
def client(test_config: GqldbConfig) -> GqldbClient:
    """Return a GQLDB client (not logged in)."""
    return GqldbClient(test_config)


@pytest.fixture
def connected_client(test_config: GqldbConfig) -> GqldbClient:
    """Return a GQLDB client that is ready to use.

    If authentication is enabled, logs in first.
    If authentication is disabled, just returns the client.
    """
    client = GqldbClient(test_config)

    if check_auth_enabled(client):
        client.login(TEST_USERNAME, TEST_PASSWORD)

    cleanup_test_graphs(client)

    yield client

    try:
        if client.is_logged_in():
            client.logout()
    except Exception:
        pass
    client.close()


@pytest.fixture
def logged_in_client(client: GqldbClient) -> GqldbClient:
    """Return a logged-in GQLDB client (skips if auth disabled)."""
    if not check_auth_enabled(client):
        pytest.skip("Authentication is not enabled on this server")

    client.login(TEST_USERNAME, TEST_PASSWORD)
    yield client
    try:
        client.logout()
    except Exception:
        pass
    client.close()


@pytest.fixture
def no_auth_config() -> GqldbConfig:
    """Return configuration for no-auth server."""
    return (
        ConfigBuilder()
        .hosts(NO_AUTH_HOST)
        .default_graph(TEST_DATABASE)
        .timeout(30)
        .build()
    )


@pytest.fixture
def no_auth_client(no_auth_config: GqldbConfig) -> GqldbClient:
    """Return a GQLDB client connected to no-auth server."""
    client = GqldbClient(no_auth_config)
    yield client
    client.close()
