"""Tests for Chutes OAuth 2.0 + PKCE authentication utilities."""

import base64
import hashlib
from urllib.parse import parse_qs, urlparse

from oro_sdk.chutes_auth import (
    _build_authorize_url,
    generate_pkce_pair,
)


class TestGeneratePkcePair:

    def test_returns_verifier_and_challenge(self):
        verifier, challenge = generate_pkce_pair()
        assert isinstance(verifier, str)
        assert isinstance(challenge, str)
        assert len(verifier) > 40

    def test_challenge_is_sha256_of_verifier(self):
        verifier, challenge = generate_pkce_pair()
        expected = base64.urlsafe_b64encode(
            hashlib.sha256(verifier.encode()).digest()
        ).rstrip(b"=").decode()
        assert challenge == expected

    def test_pairs_are_unique(self):
        pair1 = generate_pkce_pair()
        pair2 = generate_pkce_pair()
        assert pair1[0] != pair2[0]
        assert pair1[1] != pair2[1]


class TestBuildAuthorizeUrl:

    def test_includes_all_required_params(self):
        url = _build_authorize_url(
            client_id="test-client",
            redirect_uri="http://localhost:8765/callback",
            code_challenge="test-challenge",
            state="test-state",
        )
        parsed = urlparse(url)
        params = parse_qs(parsed.query)

        assert params["response_type"] == ["code"]
        assert params["client_id"] == ["test-client"]
        assert params["redirect_uri"] == ["http://localhost:8765/callback"]
        assert params["code_challenge"] == ["test-challenge"]
        assert params["code_challenge_method"] == ["S256"]
        assert params["state"] == ["test-state"]
        assert params["scope"] == ["chutes:invoke"]

    def test_uses_custom_authorize_url(self):
        url = _build_authorize_url(
            client_id="c",
            redirect_uri="http://localhost/cb",
            code_challenge="ch",
            state="s",
            authorize_url="https://custom.example.com/auth",
        )
        assert url.startswith("https://custom.example.com/auth?")


