"""
Module: test_http_utils
Description: Tests for shared HTTP client utilities

Implements:
    - docs/cli/reference.md#error-handling
    - docs/cli/reference.md#authentication
"""

from unittest.mock import MagicMock, patch

import httpx
import pytest

from huitzo_cli.http_utils import get_auth, parse_error


# --- get_auth HTTPS enforcement ---


def test_get_auth_rejects_http_non_localhost() -> None:
    """HTTPS is required for non-localhost API URLs."""
    mock_auth = MagicMock()
    mock_auth.get_token.return_value = "test-token"
    mock_auth.get_api_url.return_value = "http://evil.com"

    with (
        patch("huitzo_cli.config.ConfigManager", return_value=MagicMock()),
        patch("huitzo_cli.auth.AuthClient", return_value=mock_auth),
    ):
        from click.exceptions import Exit

        with pytest.raises(Exit):
            get_auth()


def test_get_auth_allows_https() -> None:
    """HTTPS URLs are accepted."""
    mock_auth = MagicMock()
    mock_auth.get_token.return_value = "test-token"
    mock_auth.get_api_url.return_value = "https://api.huitzo.com"

    with (
        patch("huitzo_cli.config.ConfigManager", return_value=MagicMock()),
        patch("huitzo_cli.auth.AuthClient", return_value=mock_auth),
    ):
        auth, token, api_url = get_auth()
        assert token == "test-token"
        assert api_url == "https://api.huitzo.com"


@pytest.mark.parametrize(
    "url",
    [
        "http://localhost:8000",
        "http://127.0.0.1:8000",
        "http://[::1]:8000",
    ],
)
def test_get_auth_allows_localhost(url: str) -> None:
    """Localhost HTTP URLs are allowed for development."""
    mock_auth = MagicMock()
    mock_auth.get_token.return_value = "test-token"
    mock_auth.get_api_url.return_value = url

    with (
        patch("huitzo_cli.config.ConfigManager", return_value=MagicMock()),
        patch("huitzo_cli.auth.AuthClient", return_value=mock_auth),
    ):
        _, token, api_url = get_auth()
        assert token == "test-token"
        assert api_url == url


def test_get_auth_not_authenticated() -> None:
    """Exits when no token is available."""
    mock_auth = MagicMock()
    mock_auth.get_token.return_value = None

    with (
        patch("huitzo_cli.config.ConfigManager", return_value=MagicMock()),
        patch("huitzo_cli.auth.AuthClient", return_value=mock_auth),
    ):
        from click.exceptions import Exit

        with pytest.raises(Exit):
            get_auth()


# --- parse_error ---


def test_parse_error_json_response() -> None:
    """Extracts message from JSON error response."""
    resp = MagicMock(spec=httpx.Response)
    resp.status_code = 400
    resp.json.return_value = {"error": {"message": "Bad request"}}
    assert parse_error(resp) == "Bad request"


def test_parse_error_non_json_response() -> None:
    """Returns generic HTTP status on non-JSON response."""
    resp = MagicMock(spec=httpx.Response)
    resp.status_code = 500
    resp.json.side_effect = ValueError("No JSON")
    resp.text = "<html>Internal Server Error</html>"
    assert parse_error(resp) == "HTTP 500"


def test_parse_error_string_error() -> None:
    """Handles string error field (not a dict)."""
    resp = MagicMock(spec=httpx.Response)
    resp.status_code = 422
    resp.json.return_value = {"error": "Validation failed"}
    assert parse_error(resp) == "Validation failed"
