"""Server-side X25519 keypair generation for user bootstrap.

This is the documented compromise side of the E2E design: when a user has
no chat key yet (never logged in since the feature shipped, or freshly
created), the server generates a keypair so colleagues can DM them
immediately. The private key sits in `UserKey.private_key_escrow` until
the user first logs in and claims it (then escrow is wiped).
"""
import base64

from nacl.public import PrivateKey


def generate_keypair() -> tuple[str, str]:
    """Return (public_key_b64, private_key_b64) — both standard base64."""
    sk = PrivateKey.generate()
    pk = sk.public_key
    return (
        base64.b64encode(bytes(pk)).decode('ascii'),
        base64.b64encode(bytes(sk)).decode('ascii'),
    )


def ensure_userkey(user) -> 'UserKey':  # noqa: F821
    """Create a UserKey for `user` if missing. Idempotent."""
    from .models import UserKey
    key = UserKey.objects.filter(user=user).first()
    if key:
        return key
    pub, priv = generate_keypair()
    return UserKey.objects.create(
        user=user,
        public_key=pub,
        private_key_escrow=priv,
        escrow_claimed=False,
    )
