"""Tests for V3 Auth API."""

import pytest
from pytest_httpx import HTTPXMock

from concentriq import ConcentriqClient
from concentriq.auth import ApiKeyAuth, BasicAuth
from concentriq.exceptions import AuthenticationError


class TestAuthWhoAmI:
    """Tests for Auth.whoami() behavior."""

    def test_whoami_returns_user_info_and_role_rules(self, httpx_mock: HTTPXMock):
        """WhoAmI should return current user ID and role rules."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/whoami",
            json={
                "userId": 123,
                "roleRules": [
                    ["read", "imageSets"],
                    ["create", "annotations"],
                ],
            },
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v3.auth.whoami()

        assert result["userId"] == 123
        assert isinstance(result["roleRules"], list)
        assert len(result["roleRules"]) == 2


class TestAuthGetPublicKey:
    """Tests for Auth.get_public_key() behavior."""

    def test_get_public_key_returns_jwt_public_key(self, httpx_mock: HTTPXMock):
        """Get public key should return JWT signing public key."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/token/public-key",
            json={"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjAN..."},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v3.auth.get_public_key()

        assert "publicKey" in result
        assert result["publicKey"].startswith("-----BEGIN PUBLIC KEY-----")


class TestAuthCreateToken:
    """Tests for Auth.create_token() behavior."""

    def test_create_token_returns_jwt(self, httpx_mock: HTTPXMock):
        """Create token should return a JWT auth token."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/token",
            method="POST",
            json={"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com",
            auth=BasicAuth("user@example.com", "password"),
        )
        result = client.v3.auth.create_token()

        assert "token" in result
        assert result["token"].startswith("eyJ")

    def test_create_token_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """Create token should raise AuthenticationError for invalid credentials."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/token",
            method="POST",
            status_code=401,
            json={"error": "Invalid credentials"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com",
            auth=BasicAuth("user@example.com", "wrong-password"),
        )

        with pytest.raises(AuthenticationError):
            client.v3.auth.create_token()


class TestAuthCreateApiKey:
    """Tests for Auth.create_api_key() behavior."""

    def test_create_api_key_returns_new_key(self, httpx_mock: HTTPXMock):
        """Create API key should return a new API key."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key",
            method="POST",
            status_code=201,
            json={"apiKey": "cr_1234567890abcdef"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com",
            auth=BasicAuth("user@example.com", "password"),
        )
        result = client.v3.auth.create_api_key()

        assert "apiKey" in result
        assert result["apiKey"].startswith("cr_")

    def test_create_api_key_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """Create API key should raise AuthenticationError when not authenticated."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key",
            method="POST",
            status_code=401,
            json={"error": "Unauthorized"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com",
            auth=BasicAuth("invalid", "invalid"),
        )

        with pytest.raises(AuthenticationError):
            client.v3.auth.create_api_key()


class TestAuthDeleteApiKey:
    """Tests for Auth.delete_api_key() behavior."""

    def test_delete_api_key_returns_success(self, httpx_mock: HTTPXMock):
        """Delete API key should complete successfully."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key",
            method="DELETE",
            status_code=204,
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v3.auth.delete_api_key()

        assert result is None

    def test_delete_api_key_raises_authentication_error_when_unauthorized(
        self, httpx_mock: HTTPXMock
    ):
        """Delete API key should raise AuthenticationError when not authenticated."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key",
            method="DELETE",
            status_code=401,
            json={"error": "Unauthorized"},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("invalid-key")
        )

        with pytest.raises(AuthenticationError):
            client.v3.auth.delete_api_key()


class TestAuthCheckApiKeyStatus:
    """Tests for Auth.check_api_key_status() behavior."""

    def test_check_api_key_status_returns_active_true(self, httpx_mock: HTTPXMock):
        """Check API key status should return active=True when key exists."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key/status",
            json={"active": True},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com", auth=ApiKeyAuth("test-key")
        )
        result = client.v3.auth.check_api_key_status()

        assert result["active"] is True

    def test_check_api_key_status_returns_active_false(self, httpx_mock: HTTPXMock):
        """Check API key status should return active=False when no key exists."""
        httpx_mock.add_response(
            url="https://test.concentriq.com/api/v3/auth/key/status",
            json={"active": False},
        )

        client = ConcentriqClient(
            base_url="https://test.concentriq.com",
            auth=BasicAuth("user@example.com", "password"),
        )
        result = client.v3.auth.check_api_key_status()

        assert result["active"] is False
