package middleware

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

	"github.com/gin-gonic/gin"
)

// TestCSRF_WebhookIngressPrefixExempt pins that the generic inbound webhook
// ingress (/webhooks/:namespace/*path, NCRM-INT-04 / #338) is exempt from CSRF
// — provider servers supply neither Origin/Referer nor the double-submit token
// — while the permission-gated /connector-webhooks admin API and other
// state-changing routes stay protected. A server-to-server POST is simulated by
// sending no Origin/Referer header and no _csrf cookie/header.
func TestCSRF_WebhookIngressPrefixExempt(t *testing.T) {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.Use(CSRF())
	ok := func(c *gin.Context) { c.Status(http.StatusOK) }
	r.POST("/webhooks/:namespace/*path", ok)
	r.POST("/connector-webhooks/*path", ok)
	r.POST("/oauth2/token", ok)
	r.POST("/services/oauth2/token", ok)
	r.POST("/mcp", ok)
	r.POST("/api/records", ok)

	cases := []struct {
		name       string
		path       string
		wantStatus int
	}{
		{"webhook_ingress_exempt", "/webhooks/acme/default", http.StatusOK},
		{"webhook_ingress_nested_path_exempt", "/webhooks/acme/orders/default", http.StatusOK},
		{"connector_webhooks_admin_still_protected", "/connector-webhooks/secrets", http.StatusForbidden},
		{"neutral_oauth_token_still_exempt", "/oauth2/token", http.StatusOK},
		{"oauth_token_still_exempt", "/services/oauth2/token", http.StatusOK},
		{"mcp_is_exempt_for_its_route_local_protocol_gate", "/mcp", http.StatusOK},
		{"other_state_change_protected", "/api/records", http.StatusForbidden},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			w := httptest.NewRecorder()
			req := httptest.NewRequest(http.MethodPost, tc.path, nil)
			r.ServeHTTP(w, req)
			if w.Code != tc.wantStatus {
				t.Fatalf("POST %s → %d, want %d", tc.path, w.Code, tc.wantStatus)
			}
		})
	}
}
