"""Symmetric encryption helper for operator secrets stored in the DB.

``DECNET_SECRET_KEY`` must be a URL-safe base64-encoded 32-byte Fernet key
(generate once with ``python -m decnet.web.db.secrets``).  The env var is
read lazily — at the call site of ``encrypt_secret``/``decrypt_secret`` —
so processes that never touch encrypted columns start up without it.

Fail-closed: a missing or malformed key raises ``RuntimeError`` before any
plaintext is encrypted or any ciphertext is decrypted.
"""
from __future__ import annotations

import os

from cryptography.fernet import Fernet, InvalidToken


def _load_key() -> bytes:
    key = os.environ.get("DECNET_SECRET_KEY", "")
    if not key:
        raise RuntimeError(
            "DECNET_SECRET_KEY is not set — cannot encrypt/decrypt secrets. "
            "Generate a key with: python -c \"from cryptography.fernet import Fernet; "
            "print(Fernet.generate_key().decode())\""
        )
    return key.encode()


def encrypt_secret(plaintext: str) -> str:
    """Return a Fernet ciphertext token for *plaintext*."""
    return Fernet(_load_key()).encrypt(plaintext.encode()).decode()


def decrypt_secret(ciphertext: str) -> str:
    """Decrypt a Fernet ciphertext token; raises ``InvalidToken`` if tampered."""
    try:
        return Fernet(_load_key()).decrypt(ciphertext.encode()).decode()
    except InvalidToken:
        raise


if __name__ == "__main__":
    print(Fernet.generate_key().decode())
