"""Unit tests for brokr.store encryption and storage engine."""

from brokr.store import (
    BrokrError,
    decrypt,
    derive_key,
    encrypt,
    load_store,
    save_store,
)


class TestDeriveKey:
    def test_returns_32_bytes(self):
        key = derive_key("passphrase", b"0" * 16)
        assert len(key) == 32

    def test_deterministic(self):
        salt = b"a" * 16
        assert derive_key("pw", salt) == derive_key("pw", salt)

    def test_different_passphrase_different_key(self):
        salt = b"b" * 16
        assert derive_key("pw1", salt) != derive_key("pw2", salt)


class TestEncryptDecrypt:
    def test_round_trip(self):
        key = derive_key("test", b"s" * 16)
        plaintext = b"hello world"
        ciphertext = encrypt(plaintext, key)
        assert decrypt(ciphertext, key) == plaintext

    def test_round_trip_empty(self):
        key = derive_key("test", b"s" * 16)
        ciphertext = encrypt(b"", key)
        assert decrypt(ciphertext, key) == b""

    def test_wrong_key_raises_brokr_error(self):
        key1 = derive_key("right", b"s" * 16)
        key2 = derive_key("wrong", b"s" * 16)
        ciphertext = encrypt(b"secret", key1)
        try:
            decrypt(ciphertext, key2)
            assert False, "Expected BrokrError"
        except BrokrError:
            pass

    def test_nonce_prepended(self):
        key = derive_key("test", b"s" * 16)
        ciphertext = encrypt(b"data", key)
        assert len(ciphertext) > 12


class TestLoadSaveStore:
    def test_empty_store_returns_default(self, tmp_path):
        result = load_store("pw", store_dir=tmp_path)
        assert result == {"secrets": {}}

    def test_round_trip(self, tmp_path):
        data = {"secrets": {"API_KEY": "abc123"}}
        save_store(data, "pw", store_dir=tmp_path)
        loaded = load_store("pw", store_dir=tmp_path)
        assert loaded == data

    def test_wrong_passphrase(self, tmp_path):
        save_store({"secrets": {}}, "right", store_dir=tmp_path)
        try:
            load_store("wrong", store_dir=tmp_path)
            assert False, "Expected BrokrError"
        except BrokrError:
            pass

    def test_salt_file_created(self, tmp_path):
        save_store({"secrets": {}}, "pw", store_dir=tmp_path)
        salt_file = tmp_path / "salt"
        assert salt_file.exists()
        assert len(salt_file.read_bytes()) == 16

    def test_salt_reused_across_saves(self, tmp_path):
        save_store({"secrets": {"A": "1"}}, "pw", store_dir=tmp_path)
        salt1 = (tmp_path / "salt").read_bytes()
        save_store({"secrets": {"A": "2"}}, "pw", store_dir=tmp_path)
        salt2 = (tmp_path / "salt").read_bytes()
        assert salt1 == salt2

    def test_store_file_created(self, tmp_path):
        save_store({"secrets": {}}, "pw", store_dir=tmp_path)
        assert (tmp_path / "store.enc").exists()
