"""SP9 — macOS Keychain secret accessor tests."""

from __future__ import annotations

from unittest.mock import patch

import pytest

from cyclone import secrets
from cyclone.secrets import STUB_SECRET, get_secret, has_keyring, set_secret


def test_has_keyring_true_when_lib_present():
    # The test env has keyring installed
    assert has_keyring() is True


def test_get_secret_returns_none_when_keyring_missing(monkeypatch):
    monkeypatch.setattr(secrets, "_HAS_KEYRING", False)
    monkeypatch.setattr(secrets, "keyring", None)
    assert get_secret("anything") is None


def test_get_secret_returns_keychain_value():
    with patch("cyclone.secrets.keyring") as mock_kr:
        mock_kr.get_password.return_value = "p@ssw0rd"
        v = get_secret("sftp.gainwell.password")
    assert v == "p@ssw0rd"
    mock_kr.get_password.assert_called_once_with("cyclone", "sftp.gainwell.password")


def test_get_secret_returns_none_on_keychain_exception():
    with patch("cyclone.secrets.keyring") as mock_kr:
        mock_kr.get_password.side_effect = RuntimeError("keychain locked")
        v = get_secret("x")
    assert v is None


def test_set_secret_returns_true_on_success():
    with patch("cyclone.secrets.keyring") as mock_kr:
        assert set_secret("a", "b") is True
    mock_kr.set_password.assert_called_once_with("cyclone", "a", "b")


def test_set_secret_returns_false_when_keyring_missing(monkeypatch):
    monkeypatch.setattr(secrets, "_HAS_KEYRING", False)
    monkeypatch.setattr(secrets, "keyring", None)
    assert set_secret("a", "b") is False


def test_set_secret_returns_false_on_keychain_exception():
    with patch("cyclone.secrets.keyring") as mock_kr:
        mock_kr.set_password.side_effect = RuntimeError("denied")
        assert set_secret("a", "b") is False


def test_stub_secret_is_distinct_string():
    assert STUB_SECRET == "<stub-secret>"
    assert STUB_SECRET != ""
