package cluster

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

	"github.com/stretchr/testify/require"
	"k8s.io/client-go/kubernetes/fake"

	"github.com/tidbcloud/clusterproxy/resolve"
	"github.com/tidbcloud/clusterproxy/route"
)

func TestParseDWWorkerURLPath(t *testing.T) {
	testCases := []struct {
		Name                  string
		Path                  string
		ExpectedDWWorkerID    string
		ExpectedProcessedPath string
	}{
		{
			Name:                  "normal case",
			Path:                  "/test1/info",
			ExpectedDWWorkerID:    "test1",
			ExpectedProcessedPath: "/info",
		},
		{
			Name:                  "normal case2",
			Path:                  "/test-123/info",
			ExpectedDWWorkerID:    "test-123",
			ExpectedProcessedPath: "/info",
		},
		{
			Name:                  "normal case3",
			Path:                  "/test_123/info",
			ExpectedDWWorkerID:    "test_123",
			ExpectedProcessedPath: "/info",
		},
		{
			Name:                  "empty path",
			Path:                  "/",
			ExpectedDWWorkerID:    "",
			ExpectedProcessedPath: "",
		},
		{
			Name:                  "empty path 2",
			Path:                  "",
			ExpectedDWWorkerID:    "",
			ExpectedProcessedPath: "",
		},
		{
			Name:                  "double leading path",
			Path:                  "//test1//info",
			ExpectedDWWorkerID:    "test1",
			ExpectedProcessedPath: "/info",
		},
		{
			Name:                  "single level",
			Path:                  "/test1",
			ExpectedDWWorkerID:    "test1",
			ExpectedProcessedPath: "/",
		},
	}
	for _, tc := range testCases {
		t.Run(tc.Name, func(t *testing.T) {
			importID, processedPath := parseImportURLPath(tc.Path)
			require.Equal(t, tc.ExpectedDWWorkerID, importID)
			require.Equal(t, tc.ExpectedProcessedPath, processedPath)
		})
	}
}

func TestDWWorkerGetHandler(t *testing.T) {
	req := &http.Request{
		URL: &url.URL{Path: "/test1/info"},
	}
	recorder := httptest.NewRecorder()

	dwWorkerGetHandler := NewDWWorkerGetHandlerBuilder(func(c *route.Context, cl resolve.Cluster, dwWorkerID string) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			fmt.Println(r.URL)
			switch r.URL.Path {
			case "/info":
				w.WriteHeader(http.StatusOK)
				_, err := fmt.Fprintf(w, "Hello, dwworker %s!", dwWorkerID)
				require.NoError(t, err)
			default:
				w.WriteHeader(http.StatusNotFound)
			}
		})
	}).Build()

	ctx := &route.Context{
		Cli: fake.NewSimpleClientset(),
	}
	cl := resolve.Cluster{Name: "db", Namespace: "tidb42"}
	dwWorkerGetHandler(ctx, cl).ServeHTTP(recorder, req)
	require.Equal(t, http.StatusOK, recorder.Code)
	require.Equal(t, "Hello, dwworker test1!", recorder.Body.String())
}
