package handler

import (
	"crypto/subtle"
	"fmt"
	"net/http"
)

// BasicAuthConfig configures HTTP Basic authentication middleware.
type BasicAuthConfig struct {
	Username string
	Password string
	Realm    string
}

// BasicAuthMiddleware protects routes with HTTP Basic authentication.
// If credentials are not configured, all requests are denied.
func BasicAuthMiddleware(cfg BasicAuthConfig) func(http.Handler) http.Handler {
	realm := cfg.Realm
	if realm == "" {
		realm = "Restricted"
	}

	return func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			username, password, ok := r.BasicAuth()
			if !ok || !basicAuthCredentialsMatch(username, password, cfg.Username, cfg.Password) {
				w.Header().Set("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s", charset="UTF-8"`, realm))
				writeJSON(w, http.StatusUnauthorized, map[string]string{
					"error": "unauthorized",
				})
				return
			}
			next.ServeHTTP(w, r)
		})
	}
}

func basicAuthCredentialsMatch(gotUser, gotPass, wantUser, wantPass string) bool {
	if wantUser == "" || wantPass == "" {
		return false
	}
	userOK := subtle.ConstantTimeCompare([]byte(gotUser), []byte(wantUser)) == 1
	passOK := subtle.ConstantTimeCompare([]byte(gotPass), []byte(wantPass)) == 1
	return userOK && passOK
}
