import os
from cryptography.fernet import Fernet, InvalidToken

_KEY_NAME = "BESTWEB_SECRET_KEY"


class SecretDecryptionError(RuntimeError):
    """Raised when a stored secret cannot be decrypted with the active key."""


def _fernet() -> Fernet:
    key = os.getenv(_KEY_NAME)
    if not key:
        raise RuntimeError(f"{_KEY_NAME} belum diset")
    return Fernet(key.encode())


def encrypt_secret(value: str) -> str:
    return _fernet().encrypt(value.encode()).decode()


def decrypt_secret(value: str) -> str:
    try:
        return _fernet().decrypt(value.encode()).decode()
    except (InvalidToken, ValueError):
        # Legacy plaintext values can be migrated once on save.
        return value


def decrypt_secret_strict(value: str, label: str = "secret") -> str:
    """Decrypt a secret and fail loudly instead of silently returning ciphertext.

    Device credentials must use this: sending an undecryptable ciphertext to a
    network device produces a misleading "invalid user name or password" and
    hides the real problem.
    """
    try:
        return _fernet().decrypt(value.encode()).decode()
    except (InvalidToken, ValueError) as exc:
        raise SecretDecryptionError(
            f"{label} tersimpan dengan kunci enkripsi yang berbeda. "
            "Password tidak dapat dipulihkan dan harus diset ulang."
        ) from exc
