from __future__ import annotations

import json
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from account_registry import Account, AccountRef
from claude_health_client import ClaudeHealthClient
from claude_oauth import UsageReading
from health_client import HealthStatus


def _account(home: Path) -> Account:
    return Account(AccountRef("claude", "zync"), "Zync", home, "zync@example.com", "max", "acct_1")


def _write_credentials(home: Path) -> None:
    home.mkdir(parents=True, exist_ok=True)
    (home / ".credentials.json").write_text(
        json.dumps(
            {
                "claudeAiOauth": {
                    "accessToken": "access",
                    "refreshToken": "refresh",
                    "expiresAt": 4_100_000_000_000,
                }
            }
        ),
        encoding="utf-8",
    )


class _RecordingSession:
    rotation_flags: list[bool] = []
    backup_paths: list[Path | None] = []

    def __init__(
        self,
        credentials_path: Path,
        timeout_secs: float = 5.0,
        allow_rotation: bool = False,
        rotation_backup_path: Path | None = None,
    ) -> None:
        type(self).rotation_flags.append(allow_rotation)
        type(self).backup_paths.append(rotation_backup_path)

    def get_usage_reading(self) -> UsageReading:
        return UsageReading(payload={"five_hour": {"utilization": 5}}, access_token="access")


@pytest.fixture
def recording(monkeypatch: pytest.MonkeyPatch) -> type[_RecordingSession]:
    _RecordingSession.rotation_flags = []
    _RecordingSession.backup_paths = []
    monkeypatch.setattr(
        ClaudeHealthClient,
        "_auth_status",
        staticmethod(lambda _home, _creds, _timeout: HealthStatus.OK),
    )
    monkeypatch.setattr("claude_health_client.ClaudeOAuthSession", _RecordingSession)
    monkeypatch.setattr(
        "claude_health_client.account_has_live_session", lambda _home: False
    )
    return _RecordingSession


def test_rotation_is_on_by_default_for_the_accounts_own_file(
    recording: type[_RecordingSession], tmp_path: Path
) -> None:
    home = tmp_path / "CLAUDE_HOME"
    _write_credentials(home)

    ClaudeHealthClient().fetch(_account(home))

    assert recording.rotation_flags == [True]


def test_a_live_session_disables_rotation(
    recording: type[_RecordingSession],
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    home = tmp_path / "CLAUDE_HOME"
    _write_credentials(home)
    monkeypatch.setattr(
        "claude_health_client.account_has_live_session", lambda _home: True
    )

    ClaudeHealthClient().fetch(_account(home))

    assert recording.rotation_flags == [False]


def test_backup_path_names_the_account_in_token_rescue(
    recording: type[_RecordingSession], tmp_path: Path
) -> None:
    home = tmp_path / "CLAUDE_HOME"
    _write_credentials(home)

    ClaudeHealthClient().fetch(_account(home))

    (backup,) = recording.backup_paths
    assert backup is not None
    assert backup.name == "zync.credentials.json.auto"
    assert backup.parent.name == "token-rescue"
