package middleware

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestCORS_AllowedOriginGetsHeaders(t *testing.T) {
	h := CORS(CORSConfig{Enabled: true, AllowedOrigins: []string{"https://app.example.com"}, AllowCredentials: true})(okHandler())
	req := httptest.NewRequest(http.MethodGet, "/", nil)
	req.Header.Set("Origin", "https://app.example.com")
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, req)

	require.Equal(t, "https://app.example.com", rr.Header().Get("Access-Control-Allow-Origin"))
	require.Equal(t, "true", rr.Header().Get("Access-Control-Allow-Credentials"))
	require.Equal(t, http.StatusOK, rr.Code)
}

func TestCORS_DisallowedOriginGetsNoHeaders(t *testing.T) {
	h := CORS(CORSConfig{Enabled: true, AllowedOrigins: []string{"https://app.example.com"}})(okHandler())
	req := httptest.NewRequest(http.MethodGet, "/", nil)
	req.Header.Set("Origin", "https://evil.example.com")
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, req)
	require.Empty(t, rr.Header().Get("Access-Control-Allow-Origin"))
}

func TestCORS_PreflightReturns204(t *testing.T) {
	h := CORS(CORSConfig{Enabled: true, AllowedOrigins: []string{"https://app.example.com"}})(okHandler())
	req := httptest.NewRequest(http.MethodOptions, "/api/v1/x", nil)
	req.Header.Set("Origin", "https://app.example.com")
	req.Header.Set("Access-Control-Request-Method", "POST")
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, req)

	require.Equal(t, http.StatusNoContent, rr.Code)
	require.Equal(t, "https://app.example.com", rr.Header().Get("Access-Control-Allow-Origin"))
	require.Contains(t, rr.Header().Get("Access-Control-Allow-Methods"), "POST")
}

func TestCORS_WildcardWithoutCredentials(t *testing.T) {
	h := CORS(CORSConfig{Enabled: true, AllowedOrigins: []string{"*"}})(okHandler())
	req := httptest.NewRequest(http.MethodGet, "/", nil)
	req.Header.Set("Origin", "https://anything.example.com")
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, req)
	require.Equal(t, "*", rr.Header().Get("Access-Control-Allow-Origin"))
}

func TestCORS_DisabledIsPassthrough(t *testing.T) {
	h := CORS(CORSConfig{Enabled: false})(okHandler())
	req := httptest.NewRequest(http.MethodOptions, "/", nil)
	req.Header.Set("Origin", "https://app.example.com")
	req.Header.Set("Access-Control-Request-Method", "POST")
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, req)
	require.Equal(t, http.StatusOK, rr.Code, "disabled CORS must not short-circuit OPTIONS")
	require.Empty(t, rr.Header().Get("Access-Control-Allow-Origin"))
}
