from pathlib import Path

import yaml

from nebula_cert_manager.registry import RegistryManager


def test_exists_false(registry_dir, mock_sops):
    mgr = RegistryManager(registry_dir, mock_sops)
    assert mgr.exists() is False


def test_save_and_load(registry_dir, mock_sops, sample_registry):
    mgr = RegistryManager(registry_dir, mock_sops)

    captured_plaintext = {}

    def fake_encrypt(path: Path, plaintext: str, **kwargs):
        captured_plaintext["data"] = plaintext
        path.write_text(plaintext)

    mock_sops.encrypt_to_file.side_effect = fake_encrypt

    mgr.save(sample_registry)

    assert mgr.exists()
    assert mgr.ca_cert_path.read_text() == sample_registry.ca.cert
    mock_sops.encrypt_to_file.assert_called_once()

    mock_sops.decrypt.return_value = captured_plaintext["data"]
    loaded = mgr.load()

    assert loaded.ca.name == sample_registry.ca.name
    assert loaded.ca.fingerprint == sample_registry.ca.fingerprint


def test_save_with_clients(registry_dir, mock_sops, sample_registry, sample_client):
    mgr = RegistryManager(registry_dir, mock_sops)
    sample_registry.clients["laptop"] = [sample_client]

    captured = {}

    def fake_encrypt(path, plaintext, **kwargs):
        captured["data"] = plaintext
        path.write_text(plaintext)

    mock_sops.encrypt_to_file.side_effect = fake_encrypt
    mgr.save(sample_registry)

    mock_sops.decrypt.return_value = captured["data"]
    loaded = mgr.load()

    assert "laptop" in loaded.clients
    assert loaded.clients["laptop"][0].fingerprint == "def456"


def test_save_creates_sops_config_when_age_key_set(
    registry_dir, mock_sops, sample_registry
):
    mock_sops.age_key = "age1testkey123"
    mock_sops.encrypt_to_file.side_effect = lambda path, plaintext, **kwargs: (
        path.write_text(plaintext)
    )
    mgr = RegistryManager(registry_dir, mock_sops)

    mgr.save(sample_registry)

    sops_config = registry_dir / ".sops.yaml"
    assert sops_config.exists()
    data = yaml.safe_load(sops_config.read_text())
    assert data["creation_rules"][0]["age"] == "age1testkey123"
    assert data["creation_rules"][0]["encrypted_regex"] == "key$"


def test_save_skips_sops_config_when_no_age_key(
    registry_dir, mock_sops, sample_registry
):
    mock_sops.age_key = None
    mock_sops.encrypt_to_file.side_effect = lambda path, plaintext, **kwargs: (
        path.write_text(plaintext)
    )
    mgr = RegistryManager(registry_dir, mock_sops)

    mgr.save(sample_registry)

    assert not (registry_dir / ".sops.yaml").exists()


def test_save_does_not_overwrite_existing_sops_config(
    registry_dir, mock_sops, sample_registry
):
    mock_sops.age_key = "age1newkey"
    mock_sops.encrypt_to_file.side_effect = lambda path, plaintext, **kwargs: (
        path.write_text(plaintext)
    )
    mgr = RegistryManager(registry_dir, mock_sops)
    registry_dir.mkdir(parents=True, exist_ok=True)
    (registry_dir / ".sops.yaml").write_text("existing config\n")

    mgr.save(sample_registry)

    assert (registry_dir / ".sops.yaml").read_text() == "existing config\n"
