"""Unit tests for navari_cli.config module."""

import msal
import pytest
from navari_cli.config import NavariConfig


class TestNavariConfig:
    @pytest.fixture(autouse=True)
    def _use_tmp_config(self, tmp_path, monkeypatch):
        """Redirect NavariConfig to a temporary directory."""
        monkeypatch.setattr(NavariConfig, "CONFIG_DIR", tmp_path)
        monkeypatch.setattr(NavariConfig, "CREDENTIALS_FILE", tmp_path / "credentials.json")
        monkeypatch.setattr(NavariConfig, "CONFIG_FILE", tmp_path / "config.json")
        monkeypatch.setattr(NavariConfig, "MSAL_CACHE_FILE", tmp_path / "msal_cache.json")

    def test_save_and_load_credentials(self):
        NavariConfig.save_credentials("https://example.com", "tok123", "user@test.com")
        token, user = NavariConfig.load_credentials("https://example.com")
        assert token == "tok123"
        assert user == "user@test.com"

    def test_load_credentials_missing_file(self):
        with pytest.raises(FileNotFoundError):
            NavariConfig.load_credentials("https://example.com")

    def test_load_credentials_missing_server(self):
        NavariConfig.save_credentials("https://other.com", "tok", "user")
        with pytest.raises(KeyError):
            NavariConfig.load_credentials("https://example.com")

    def test_save_with_auth_config(self):
        auth = {"client_id": "abc", "authority": "https://login.example.com"}
        NavariConfig.save_credentials("https://s.com", "tok", "user", auth)
        loaded = NavariConfig.load_auth_config("https://s.com")
        assert loaded == auth

    def test_load_auth_config_missing(self):
        assert NavariConfig.load_auth_config("https://nonexistent.com") is None

    def test_delete_specific_server(self):
        NavariConfig.save_credentials("https://a.com", "t1", "u1")
        NavariConfig.save_credentials("https://b.com", "t2", "u2")
        NavariConfig.delete_credentials("https://a.com")
        with pytest.raises(KeyError):
            NavariConfig.load_credentials("https://a.com")
        token, _ = NavariConfig.load_credentials("https://b.com")
        assert token == "t2"

    def test_delete_all(self):
        NavariConfig.save_credentials("https://a.com", "t1", "u1")
        NavariConfig.delete_credentials(None)
        assert not NavariConfig.CREDENTIALS_FILE.exists()

    def test_last_used_server(self):
        assert NavariConfig.get_last_used_server() is None
        NavariConfig.set_last_used_server("https://s.com")
        assert NavariConfig.get_last_used_server() == "https://s.com"
        NavariConfig.set_last_used_server(None)
        assert NavariConfig.get_last_used_server() is None

    def test_list_saved_servers(self):
        assert NavariConfig.list_saved_servers() == []
        NavariConfig.save_credentials("https://a.com", "t1", "u1")
        NavariConfig.save_credentials("https://b.com", "t2", "u2")
        servers = NavariConfig.list_saved_servers()
        assert set(servers) == {"https://a.com", "https://b.com"}

    def test_msal_cache_roundtrip(self):
        cache = msal.SerializableTokenCache()
        cache.deserialize('{"AccessToken": {}, "RefreshToken": {}}')
        cache.has_state_changed = True
        NavariConfig.save_msal_cache(cache)
        loaded = NavariConfig.load_msal_cache()
        assert isinstance(loaded, msal.SerializableTokenCache)

    def test_msal_cache_missing_file(self):
        cache = NavariConfig.load_msal_cache()
        assert isinstance(cache, msal.SerializableTokenCache)

    def test_set_and_get_server_option(self):
        NavariConfig.save_credentials("https://s.com", "tok", "user")
        NavariConfig.set_server_option("https://s.com", "verify_ssl", False)
        assert NavariConfig.get_server_option("https://s.com", "verify_ssl") is False
        # Default when option not set
        assert NavariConfig.get_server_option("https://s.com", "missing_key", True) is True

    def test_get_server_option_no_credentials(self):
        assert NavariConfig.get_server_option("https://s.com", "verify_ssl", True) is True

    def test_server_option_preserved_on_save(self):
        """verify_ssl setting survives a save_credentials call."""
        NavariConfig.save_credentials("https://s.com", "tok1", "user1")
        NavariConfig.set_server_option("https://s.com", "verify_ssl", False)
        # Re-save credentials (e.g. token refresh)
        NavariConfig.save_credentials("https://s.com", "tok2", "user2")
        assert NavariConfig.get_server_option("https://s.com", "verify_ssl") is False

    def test_corrupted_credentials_file(self, tmp_path):
        NavariConfig.CREDENTIALS_FILE.write_text("not json")
        NavariConfig.save_credentials("https://s.com", "tok", "user")
        token, _ = NavariConfig.load_credentials("https://s.com")
        assert token == "tok"
