"""Password hashing for the client portal — argon2id via argon2-cffi.

Kept separate from portal_auth (cookie signing) so the future operator auth can
reuse the same hasher. Never store or log raw passwords."""
import secrets
from argon2 import PasswordHasher

_ph = PasswordHasher()


def hash_password(raw: str) -> str:
    """Return an argon2id hash string for a raw password."""
    return _ph.hash(raw)


def verify_password(raw: str, hashed: str) -> bool:
    """True iff raw matches the stored hash. Never raises."""
    try:
        return _ph.verify(hashed, raw)
    except Exception:  # argon2 raises on mismatch/garbage; treat all as "no match"
        return False


def generate_password(n_bytes: int = 12) -> str:
    """A strong, URL-safe shareable password (~16 chars for n_bytes=12)."""
    return secrets.token_urlsafe(n_bytes)
