package api

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"time"
)

// SignStreamToken returns the HMAC-SHA256 hex of "<trackID>|<exp>" keyed
// by secret. The token is constant-time-comparable via VerifyStreamToken
// so it's safe to expose the verification function in handlers.
//
// trackID is the canonical track UUID. exp is the Unix time after which
// the token is invalid; the handler checks exp before serving.
//
// The secret comes from MINSTREL_STREAM_SECRET (or its auto-generated +
// persisted fallback in app_preferences). The loader lands in slice 2
// (POST /api/cast/stream-token); this file is the primitive both the
// loader and the stream handler share.
func SignStreamToken(secret []byte, trackID string, exp int64) string {
	mac := hmac.New(sha256.New, secret)
	// hash.Hash.Write is documented as never returning an error.
	_, _ = fmt.Fprintf(mac, "%s|%d", trackID, exp)
	return hex.EncodeToString(mac.Sum(nil))
}

// VerifyStreamToken returns true iff token is a valid HMAC for
// (trackID, exp) AND exp has not yet passed. Wall-clock comparison —
// callers must trust the server's clock. Uses hmac.Equal for
// constant-time compare so a timing oracle can't bias token guessing.
func VerifyStreamToken(secret []byte, trackID string, exp int64, token string) bool {
	if time.Now().Unix() > exp {
		return false
	}
	expected := SignStreamToken(secret, trackID, exp)
	return hmac.Equal([]byte(expected), []byte(token))
}
