package router

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

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/inference-service/internal/config"
)

func TestRequireServiceAPIKey(t *testing.T) {
	gin.SetMode(gin.TestMode)

	tests := []struct {
		name           string
		configAPIKey   string
		authHeader     string
		expectedStatus int
		shouldCallNext bool
	}{
		{
			name:           "no api key configured - should pass",
			configAPIKey:   "",
			authHeader:     "",
			expectedStatus: http.StatusOK,
			shouldCallNext: true,
		},
		{
			name:           "missing auth header when api key configured",
			configAPIKey:   "test-key",
			authHeader:     "",
			expectedStatus: http.StatusUnauthorized,
			shouldCallNext: false,
		},
		{
			name:           "invalid auth header format",
			configAPIKey:   "test-key",
			authHeader:     "Basic dGVzdA==",
			expectedStatus: http.StatusUnauthorized,
			shouldCallNext: false,
		},
		{
			name:           "wrong api key",
			configAPIKey:   "test-key",
			authHeader:     "Bearer wrong-key",
			expectedStatus: http.StatusUnauthorized,
			shouldCallNext: false,
		},
		{
			name:           "correct api key",
			configAPIKey:   "test-key",
			authHeader:     "Bearer test-key",
			expectedStatus: http.StatusOK,
			shouldCallNext: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Load config with test API key
			err := config.LoadConfig("")
			require.NoError(t, err)

			// Override the service API key
			cfg := config.Global()
			cfg.Server.CheckServiceAPIKey = tt.configAPIKey

			// Create test router
			router := gin.New()
			router.Use(mCatchError)
			nextCalled := false

			router.GET("/test", RequireServiceAPIKey(), func(c *gin.Context) {
				nextCalled = true
				c.JSON(http.StatusOK, gin.H{"message": "success"})
			})

			// Create test request
			req := httptest.NewRequest("GET", "/test", nil)
			if tt.authHeader != "" {
				req.Header.Set("Authorization", tt.authHeader)
			}

			w := httptest.NewRecorder()
			router.ServeHTTP(w, req)

			// Verify response
			require.Equal(t, tt.expectedStatus, w.Code)
			require.Equal(t, tt.shouldCallNext, nextCalled)
		})
	}
}
