"""Session Service integration tests."""

import pytest

from gqldb.client import GqldbClient
from gqldb.config import GqldbConfig
from gqldb.errors import GqldbError
from tests.conftest import check_auth_enabled, TEST_USERNAME, TEST_PASSWORD


@pytest.mark.integration
class TestSession:
    """Tests for session operations (login/logout/ping)."""

    def test_login_success(self, client: GqldbClient):
        """Test successful login (skips if auth disabled)."""
        if not check_auth_enabled(client):
            pytest.skip("Authentication is not enabled on this server")

        session = client.login(TEST_USERNAME, TEST_PASSWORD)
        assert session is not None
        assert session.id > 0
        assert client.is_logged_in()
        client.logout()
        client.close()

    def test_login_when_auth_disabled(self, client: GqldbClient):
        """Test login behavior when authentication is disabled."""
        if check_auth_enabled(client):
            pytest.skip("Authentication is enabled on this server")

        from gqldb.errors import GqldbError
        with pytest.raises(GqldbError) as exc_info:
            client.login(TEST_USERNAME, TEST_PASSWORD)
        assert "authentication is not enabled" in str(exc_info.value).lower()
        client.close()

    def test_logout(self, client: GqldbClient):
        """Test logout (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)
        assert client.is_logged_in()
        client.logout()
        assert not client.is_logged_in()
        client.close()

    def test_client_context_manager(self, test_config: GqldbConfig):
        """Test client as context manager (skips if auth disabled)."""
        with GqldbClient(test_config) as client:
            if not check_auth_enabled(client):
                pytest.skip("Authentication is not enabled on this server")
            client.login(TEST_USERNAME, TEST_PASSWORD)
            assert client.is_logged_in()

    def test_ping(self, connected_client: GqldbClient):
        """Test ping operation."""
        latency = connected_client.ping()
        assert latency >= 0
        print(f"Ping latency: {latency} ns")


@pytest.mark.integration
class TestSessionNoAuth:
    """Tests for server without authentication (192.168.1.104:60062)."""

    def test_ping_without_login(self, no_auth_client: GqldbClient):
        """Test ping works without login on no-auth server."""
        latency = no_auth_client.ping()
        assert latency >= 0
        print(f"No-auth server ping latency: {latency} ns")

    def test_login_returns_error(self, no_auth_client: GqldbClient):
        """Test login returns 'authentication is not enabled' error."""
        with pytest.raises(GqldbError) as exc_info:
            no_auth_client.login(TEST_USERNAME, TEST_PASSWORD)
        assert "authentication is not enabled" in str(exc_info.value).lower()

    def test_query_without_login(self, no_auth_client: GqldbClient):
        """Test query works without login on no-auth server."""
        try:
            resp = no_auth_client.gql("MATCH (n) RETURN n LIMIT 1")
            assert resp is not None
            print(f"Query returned {resp.row_count} rows without login")
        except GqldbError as e:
            # If graph not found, that's ok - the point is we can execute without auth
            if "not found" in str(e).lower():
                print(f"Graph not found (expected on clean server): {e}")
            else:
                raise
