package connectsrv

import "net/http"

// nativeWebViewOrigins are the browser Origins of the packaged native apps. Capacitor serves the
// bundled SPA from a localhost scheme, so its Connect calls to the gateway are cross-origin; the web
// app is same-origin and needs no entry. Requests carry Authorization, so the allowlist reflects the
// exact origin rather than "*".
var nativeWebViewOrigins = map[string]bool{
	"https://localhost":     true, // Capacitor Android (default https scheme)
	"http://localhost":      true, // Capacitor with the http scheme
	"capacitor://localhost": true, // Capacitor iOS default scheme
}

// withNativeCORS answers the CORS preflight and adds the CORS response headers for the packaged
// native apps' cross-origin calls to the Connect edge. Without it the WebView blocks every RPC on the
// preflight (the gateway otherwise returns 405 with no Access-Control-Allow-Origin), so a native
// build can never reach the gateway and stays stuck offline. Same-origin (web) and any non-native
// origin are untouched.
func withNativeCORS(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		origin := r.Header.Get("Origin")
		if nativeWebViewOrigins[origin] {
			h := w.Header()
			h.Set("Access-Control-Allow-Origin", origin)
			h.Add("Vary", "Origin")
			h.Set("Access-Control-Allow-Credentials", "true")
			// The client interceptor reads the soft-tier update signal off the response.
			h.Set("Access-Control-Expose-Headers", "X-Update-Recommended")
			if r.Method == http.MethodOptions {
				h.Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
				// Reflect the requested headers (the origin is already allowlisted): the Connect client
				// sends Connect-Protocol-Version / Connect-Timeout-Ms plus X-Client-Version and
				// Authorization, and the exact set varies by call.
				if reqHeaders := r.Header.Get("Access-Control-Request-Headers"); reqHeaders != "" {
					h.Set("Access-Control-Allow-Headers", reqHeaders)
				} else {
					h.Set("Access-Control-Allow-Headers", "Content-Type, Connect-Protocol-Version, X-Client-Version, Authorization")
				}
				h.Set("Access-Control-Max-Age", "86400")
				w.WriteHeader(http.StatusNoContent)
				return
			}
		}
		next.ServeHTTP(w, r)
	})
}
