from __future__ import annotations

"""AES-256-GCM utilities for QQBot scan-to-configure credential decryption."""


import base64
import os


def generate_bind_key() -> str:
    """Generate a 256-bit random AES key and return it as base64.

    The key is passed to ``create_bind_task`` so the server can encrypt
    the bot's *client_secret* before returning it.  Only this CLI holds
    the key, ensuring the secret never travels in plaintext.
    """
    return base64.b64encode(os.urandom(32)).decode()


def decrypt_secret(encrypted_base64: str, key_base64: str) -> str:
    """Decrypt a base64-encoded AES-256-GCM ciphertext.

    Ciphertext layout (after base64-decoding)::

        IV (12 bytes) ‖ ciphertext (N bytes) ‖ AuthTag (16 bytes)

    Args:
        encrypted_base64: The ``bot_encrypt_secret`` value from
            ``poll_bind_result``.
        key_base64: The base64 AES key generated by
            :func:`generate_bind_key`.

    Returns:
        The decrypted *client_secret* as a UTF-8 string.
    """
    from cryptography.hazmat.primitives.ciphers.aead import AESGCM

    key = base64.b64decode(key_base64)
    raw = base64.b64decode(encrypted_base64)

    iv = raw[:12]
    ciphertext_with_tag = raw[12:]  # AESGCM expects ciphertext + tag concatenated

    aesgcm = AESGCM(key)
    plaintext = aesgcm.decrypt(iv, ciphertext_with_tag, None)
    return plaintext.decode("utf-8")
