package main

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

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

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

	tests := []struct {
		name               string
		requestPath        string
		requestRawPath     string
		wantHandlerPath    string
		wantHandlerRawPath string
		wantEscapedPath    string
	}{
		{
			name:               "rewrite path and clear raw path for downstream handlers",
			requestPath:        "/api/v1/tidb123/clusters/test",
			requestRawPath:     "/api/v1/tidb123/clusters/test",
			wantHandlerPath:    "/clusters/test",
			wantHandlerRawPath: "",
			wantEscapedPath:    "/clusters/test",
		},
		{
			name:               "rewrite path without original raw path",
			requestPath:        "/api/v1/tidb123/healthz",
			requestRawPath:     "",
			wantHandlerPath:    "/healthz",
			wantHandlerRawPath: "",
			wantEscapedPath:    "/healthz",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			router := gin.New()

			var gotHandlerPath string
			var gotHandlerRawPath string
			var gotEscapedPath string

			router.Any("/api/v1/:tcns/*any", ServePathStartFromAny, func(c *gin.Context) {
				gotHandlerPath = c.Request.URL.Path
				gotHandlerRawPath = c.Request.URL.RawPath
				gotEscapedPath = c.Request.URL.EscapedPath()
				c.Status(http.StatusNoContent)
			})

			req := httptest.NewRequest(http.MethodGet, tt.requestPath, http.NoBody)
			req.URL.RawPath = tt.requestRawPath
			recorder := httptest.NewRecorder()

			router.ServeHTTP(recorder, req)

			if recorder.Code != http.StatusNoContent {
				t.Fatalf("ServeHTTP() status = %d, want %d", recorder.Code, http.StatusNoContent)
			}
			if gotHandlerPath != tt.wantHandlerPath {
				t.Fatalf("handler path = %q, want %q", gotHandlerPath, tt.wantHandlerPath)
			}
			if gotHandlerRawPath != tt.wantHandlerRawPath {
				t.Fatalf("handler raw path = %q, want %q", gotHandlerRawPath, tt.wantHandlerRawPath)
			}
			if gotEscapedPath != tt.wantEscapedPath {
				t.Fatalf("handler escaped path = %q, want %q", gotEscapedPath, tt.wantEscapedPath)
			}
			if req.URL.Path != tt.requestPath {
				t.Fatalf("restored request path = %q, want %q", req.URL.Path, tt.requestPath)
			}
			if req.URL.RawPath != tt.requestRawPath {
				t.Fatalf("restored request raw path = %q, want %q", req.URL.RawPath, tt.requestRawPath)
			}
		})
	}
}
