package server

import (
	"net/http"
	"slices"
)

// CORSOptions configures CORS behavior for the server HTTP API.
type CORSOptions struct {
	AllowOrigins []string // Allowed origins; default ["*"].
}

// WithCORS wraps an http.Handler with CORS headers.
func WithCORS(h http.Handler, opts CORSOptions) http.Handler {
	origins := opts.AllowOrigins
	if len(origins) == 0 {
		origins = []string{"*"}
	}
	wildcard := len(origins) == 1 && origins[0] == "*"

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		origin := r.Header.Get("Origin")
		if origin != "" {
			matched := false
			if wildcard {
				w.Header().Set("Access-Control-Allow-Origin", "*")
				matched = true
			} else if slices.Contains(origins, origin) {
				w.Header().Set("Access-Control-Allow-Origin", origin)
				w.Header().Set("Vary", "Origin")
				matched = true
			}
			if matched {
				w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
				w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
				w.Header().Set("Access-Control-Max-Age", "86400")
			}
		}

		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusNoContent)
			return
		}

		h.ServeHTTP(w, r)
	})
}
