package middleware

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

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

func okHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte("ok"))
	})
}

func TestSecurityHeaders_PresentWhenEnabled(t *testing.T) {
	h := SecurityHeaders(SecurityHeadersConfig{Enabled: true})(okHandler())
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/", nil))

	require.Equal(t, "nosniff", rr.Header().Get("X-Content-Type-Options"))
	require.Equal(t, "DENY", rr.Header().Get("X-Frame-Options"))
	require.Equal(t, "no-referrer", rr.Header().Get("Referrer-Policy"))
	require.Empty(t, rr.Header().Get("Strict-Transport-Security"), "HSTS only under TLS")
}

func TestSecurityHeaders_HSTSOnlyUnderTLS(t *testing.T) {
	h := SecurityHeaders(SecurityHeadersConfig{Enabled: true, TLSEnabled: true})(okHandler())
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/", nil))
	require.Contains(t, rr.Header().Get("Strict-Transport-Security"), "max-age=31536000")
}

func TestSecurityHeaders_DisabledIsPassthrough(t *testing.T) {
	h := SecurityHeaders(SecurityHeadersConfig{Enabled: false})(okHandler())
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/", nil))
	require.Empty(t, rr.Header().Get("X-Content-Type-Options"))
	require.Equal(t, http.StatusOK, rr.Code)
}

func TestSecurityHeaders_CSPOptIn(t *testing.T) {
	h := SecurityHeaders(SecurityHeadersConfig{Enabled: true, ContentSecurityPolicy: "default-src 'self'"})(okHandler())
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/", nil))
	require.Equal(t, "default-src 'self'", rr.Header().Get("Content-Security-Policy"))
}
