"""Shared fixtures and mandatory isolation.

Every test that touches auth state writes to the real state directory unless it
is redirected, and the real one is the user's home. The autouse fixture below
makes that structurally impossible rather than relying on each test to remember.
"""

import base64
import json
from unittest.mock import MagicMock

import pytest

from a360_mcp.auth._paths import STATE_DIR_ENV
from a360_mcp.utils.config import A360AuthConfig, ServerConfig


@pytest.fixture(autouse=True)
def isolate_state_dir(tmp_path, monkeypatch):
    """Redirect all token caches, session ledgers and locks into tmp_path."""
    state = tmp_path / "state"
    state.mkdir()
    monkeypatch.setenv(STATE_DIR_ENV, str(state))
    return state


@pytest.fixture
def auth_config() -> A360AuthConfig:
    return A360AuthConfig(username="svc_mcp", api_key="test-key")


@pytest.fixture
def server_config(auth_config) -> ServerConfig:
    return ServerConfig(control_room_url="https://cr.example.com", auth=auth_config)


@pytest.fixture
def make_response():
    """Build a mock HTTP response whose json()/content agree with each other."""

    def _build(body: dict | None = None, *, status_code: int = 200):
        response = MagicMock()
        response.status_code = status_code
        response.json.return_value = body or {}
        response.content = json.dumps(body or {}).encode("utf-8")
        response.text = json.dumps(body or {})
        response.headers = {}
        return response

    return _build


@pytest.fixture
def make_jwt():
    """Build an unsigned JWT carrying a given `exp`, for expiry-parsing tests."""

    def _build(exp: float | None) -> str:
        claims = {} if exp is None else {"exp": exp}
        encoded = base64.urlsafe_b64encode(json.dumps(claims).encode()).decode().rstrip("=")
        return f"header.{encoded}.signature"

    return _build
