package auth

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

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

	"github.com/tidbcloud/AgentTeam/desktop/internal/token"
)

func TestMiddlewarePublishesValidatedSessionIdentity(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.Use(Middleware())
	router.GET("/protected", func(c *gin.Context) {
		sessionID, expiresAt, ok := SessionIdentity(c)
		require.True(t, ok)
		require.False(t, expiresAt.IsZero())
		c.JSON(http.StatusOK, gin.H{"sessionId": sessionID})
	})

	sessionToken := token.CreateSession()
	req := httptest.NewRequest(http.MethodGet, "/protected", nil)
	req.Header.Set("Authorization", "Bearer "+sessionToken)
	recorder := httptest.NewRecorder()
	router.ServeHTTP(recorder, req)

	require.Equal(t, http.StatusOK, recorder.Code)
	require.Contains(t, recorder.Body.String(), sessionToken)
}

func TestMiddlewarePublishesStableLogicalUISessionIdentity(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.Use(Middleware())
	router.GET("/protected", func(c *gin.Context) {
		sessionID, _, ok := SessionIdentity(c)
		require.True(t, ok)
		c.JSON(http.StatusOK, gin.H{"sessionId": sessionID})
	})

	issue, err := token.EnsureUISession("instance-a", "window-a")
	require.NoError(t, err)
	req := httptest.NewRequest(http.MethodGet, "/protected", nil)
	req.Header.Set("Authorization", "Bearer "+issue.Token)
	recorder := httptest.NewRecorder()
	router.ServeHTTP(recorder, req)

	require.Equal(t, http.StatusOK, recorder.Code)
	require.Contains(t, recorder.Body.String(), issue.Metadata.LogicalSessionID)
	require.NotContains(t, recorder.Body.String(), issue.Token)
}

func TestMiddlewareReturnsTypedLocalSessionError(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.Use(Middleware())
	router.GET("/protected", func(c *gin.Context) { c.Status(http.StatusOK) })

	req := httptest.NewRequest(http.MethodGet, "/protected", nil)
	req.Header.Set("Authorization", "Bearer expired")
	recorder := httptest.NewRecorder()
	router.ServeHTTP(recorder, req)

	require.Equal(t, http.StatusUnauthorized, recorder.Code)
	require.Equal(t, "ui-session-invalid", recorder.Header().Get("X-AgentTeam-Desktop-Auth-Error"))
	require.Contains(t, recorder.Body.String(), DesktopUISessionInvalidCode)
}
