package auth

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"fmt"
)

// TokenLen is the number of random bytes in session, CSRF, and
// enrollment tokens. 32 bytes = 256 bits of entropy, more than enough
// to be unguessable.
const TokenLen = 32

// NewToken returns a fresh URL-safe random token. Used for session
// IDs, CSRF tokens, agent bearer tokens, and one-time enrollment
// tokens. Returns base64url(no-padding) for compactness.
func NewToken() (string, error) {
	buf := make([]byte, TokenLen)
	if _, err := rand.Read(buf); err != nil {
		return "", fmt.Errorf("auth: read random: %w", err)
	}
	return base64.RawURLEncoding.EncodeToString(buf), nil
}

// HashToken returns a hex-encoded SHA-256 of the token. We store
// this rather than the raw token so a stolen DB doesn't yield
// session/agent credentials directly. SHA-256 (not argon2) is fine
// here because the input is already 256 bits of uniform random.
func HashToken(token string) string {
	sum := sha256.Sum256([]byte(token))
	return hex.EncodeToString(sum[:])
}
