"""Tests for SDK client classes."""

import httpx
import pytest

from oro_sdk.client import AuthenticatedClient, Client


class TestClient:
    """Tests for the base Client class."""

    def test_creates_with_base_url(self):
        """Should create client with specified base URL."""
        client = Client(base_url="https://api.example.com")
        httpx_client = client.get_httpx_client()

        assert str(httpx_client.base_url) == "https://api.example.com"

    def test_with_headers_adds_headers(self):
        """Should add headers to client."""
        client = Client(base_url="https://api.example.com")
        client = client.with_headers({"X-Custom": "value"})

        httpx_client = client.get_httpx_client()
        assert httpx_client.headers["X-Custom"] == "value"

    def test_with_cookies_adds_cookies(self):
        """Should add cookies to client."""
        client = Client(base_url="https://api.example.com")
        client = client.with_cookies({"session": "abc123"})

        httpx_client = client.get_httpx_client()
        assert httpx_client.cookies["session"] == "abc123"

    def test_with_timeout_sets_timeout(self):
        """Should set timeout on client."""
        client = Client(base_url="https://api.example.com")
        timeout = httpx.Timeout(30.0)
        client = client.with_timeout(timeout)

        httpx_client = client.get_httpx_client()
        assert httpx_client.timeout == timeout

    def test_context_manager_sync(self):
        """Should work as sync context manager."""
        client = Client(base_url="https://api.example.com")

        with client as ctx:
            assert ctx is client

    @pytest.mark.asyncio
    async def test_context_manager_async(self):
        """Should work as async context manager."""
        client = Client(base_url="https://api.example.com")

        async with client as ctx:
            assert ctx is client

    def test_reuses_client_instance(self):
        """Should return same client on multiple get_httpx_client calls."""
        client = Client(base_url="https://api.example.com")

        client1 = client.get_httpx_client()
        client2 = client.get_httpx_client()

        assert client1 is client2

    def test_reuses_async_client_instance(self):
        """Should return same async client on multiple calls."""
        client = Client(base_url="https://api.example.com")

        client1 = client.get_async_httpx_client()
        client2 = client.get_async_httpx_client()

        assert client1 is client2

    def test_set_httpx_client_overrides(self):
        """Should allow manually setting the httpx client."""
        client = Client(base_url="https://api.example.com")
        custom_httpx = httpx.Client(base_url="https://custom.example.com")

        client.set_httpx_client(custom_httpx)

        assert client.get_httpx_client() is custom_httpx


class TestAuthenticatedClient:
    """Tests for the AuthenticatedClient class."""

    def test_creates_with_token(self):
        """Should create client with auth token in headers."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-secret-token",
        )
        httpx_client = client.get_httpx_client()

        assert httpx_client.headers["Authorization"] == "Bearer my-secret-token"

    def test_custom_prefix(self):
        """Should use custom auth prefix."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-token",
            prefix="Token",
        )
        httpx_client = client.get_httpx_client()

        assert httpx_client.headers["Authorization"] == "Token my-token"

    def test_no_prefix(self):
        """Should work without prefix."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-token",
            prefix="",
        )
        httpx_client = client.get_httpx_client()

        assert httpx_client.headers["Authorization"] == "my-token"

    def test_custom_header_name(self):
        """Should use custom auth header name."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-token",
            auth_header_name="X-API-Key",
            prefix="",
        )
        httpx_client = client.get_httpx_client()

        assert httpx_client.headers["X-API-Key"] == "my-token"
        assert "Authorization" not in httpx_client.headers

    def test_context_manager_sync(self):
        """Should work as sync context manager."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-token",
        )

        with client as ctx:
            assert ctx is client

    @pytest.mark.asyncio
    async def test_context_manager_async(self):
        """Should work as async context manager."""
        client = AuthenticatedClient(
            base_url="https://api.example.com",
            token="my-token",
        )

        async with client as ctx:
            assert ctx is client
