package httpcors

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

	"github.com/ultisuite/ulti-backend/internal/config"
)

func TestMiddlewareDevAllowsLocalhostOrigin(t *testing.T) {
	cfg := &config.Config{AppEnv: "development"}
	handler := Middleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))

	req := httptest.NewRequest(http.MethodGet, "/api/v1/mail/settings", nil)
	req.Header.Set("Origin", "http://localhost:3000")
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)

	if got := rec.Header().Get("Access-Control-Allow-Origin"); got != "http://localhost:3000" {
		t.Fatalf("Access-Control-Allow-Origin = %q, want http://localhost:3000", got)
	}
}

func TestMiddlewareDevAllowsPrivateLANOrigin(t *testing.T) {
	cfg := &config.Config{AppEnv: "development"}
	handler := Middleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))

	req := httptest.NewRequest(http.MethodGet, "/api/v1/mail/settings", nil)
	req.Header.Set("Origin", "http://192.168.0.20:3000")
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)

	if got := rec.Header().Get("Access-Control-Allow-Origin"); got != "http://192.168.0.20:3000" {
		t.Fatalf("Access-Control-Allow-Origin = %q, want http://192.168.0.20:3000", got)
	}
}

func TestMiddlewareDevPreflightIncludesHeadMethod(t *testing.T) {
	cfg := &config.Config{AppEnv: "development"}
	handler := Middleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))

	req := httptest.NewRequest(http.MethodOptions, "/api/v1/mail/settings", nil)
	req.Header.Set("Origin", "http://localhost:3000")
	req.Header.Set("Access-Control-Request-Method", "HEAD")
	req.Header.Set("Access-Control-Request-Headers", "authorization")
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)

	if got := rec.Header().Get("Access-Control-Allow-Methods"); got != "HEAD" {
		t.Fatalf("Access-Control-Allow-Methods = %q, want HEAD", got)
	}
}

func TestMiddlewareProductionUsesDomainOrigins(t *testing.T) {
	cfg := &config.Config{AppEnv: "production", Domain: "mail.example.com"}
	handler := Middleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))

	req := httptest.NewRequest(http.MethodGet, "/api/v1/mail/settings", nil)
	req.Header.Set("Origin", "https://mail.example.com")
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)

	if got := rec.Header().Get("Access-Control-Allow-Origin"); got != "https://mail.example.com" {
		t.Fatalf("Access-Control-Allow-Origin = %q, want https://mail.example.com", got)
	}
}

func TestMiddlewareExplicitWildcard(t *testing.T) {
	cfg := &config.Config{
		AppEnv:             "production",
		Domain:             "mail.example.com",
		CORSAllowedOrigins: []string{"*"},
	}
	handler := Middleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))

	req := httptest.NewRequest(http.MethodGet, "/api/v1/mail/settings", nil)
	req.Header.Set("Origin", "http://localhost:3000")
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)

	if got := rec.Header().Get("Access-Control-Allow-Origin"); got != "*" {
		t.Fatalf("Access-Control-Allow-Origin = %q, want *", got)
	}
}
