from __future__ import annotations

import base64
import hashlib

from codeflash_api.auth._keys import (
    extract_bearer_token,
    hash_api_key,
)


class TestHashApiKey:
    """Tests for hash_api_key."""

    def test_deterministic(self) -> None:
        """
        Same input always produces the same hash.
        """
        assert hash_api_key("test-key") == hash_api_key("test-key")

    def test_matches_manual_sha384(self) -> None:
        """
        Output matches manual SHA-384 + base64url computation.
        """
        key = "cf_live_abc123"
        expected = base64.urlsafe_b64encode(
            hashlib.sha384(key.encode("utf-8")).digest()
        ).decode("utf-8")

        assert expected == hash_api_key(key)

    def test_different_keys_produce_different_hashes(
        self,
    ) -> None:
        """
        Distinct keys never collide (within reason).
        """
        assert hash_api_key("key-a") != hash_api_key("key-b")

    def test_empty_string(self) -> None:
        """
        Empty string is hashable without error.
        """
        result = hash_api_key("")
        assert isinstance(result, str)
        assert len(result) > 0


class TestExtractBearerToken:
    """Tests for extract_bearer_token."""

    def test_strips_bearer_prefix(self) -> None:
        """
        'Bearer <token>' returns just the token.
        """
        assert "abc123" == extract_bearer_token("Bearer abc123")

    def test_no_prefix_returns_as_is(self) -> None:
        """
        Raw token without Bearer prefix is returned unchanged.
        """
        assert "raw-token" == extract_bearer_token("raw-token")

    def test_case_sensitive(self) -> None:
        """
        'bearer' (lowercase) is not stripped — only 'Bearer'.
        """
        assert "bearer abc" == extract_bearer_token("bearer abc")

    def test_empty_string(self) -> None:
        """
        Empty string returns empty string.
        """
        assert "" == extract_bearer_token("")
