package main

import (
	"net/http"
	"regexp"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestA(t *testing.T) {
	mp := map[string]string{
		"/aa":                        "/aa",
		"/":                          "/",
		"":                           "",
		"/terminal/19/root/":         "/cluster/19/terminal/root/",
		"/terminal/19/alei/":         "/cluster/19/terminal/alei/",
		"/terminal/19/root/keep/":    "/cluster/19/terminal/root/keep/",
		"/terminal/19/root/?a=1&b=b": "/cluster/19/terminal/root/?a=1&b=b",
		"/terminal/invalid":          "/terminal/invalid",
	}

	for origin, res := range mp {
		get := rewriteTerminalPath(origin)
		require.Equal(t, res, get)

		if origin != "" {
			get = rewriteTerminalPath(origin[1:])
			require.Equal(t, res[1:], get)
		}
	}
}

func TestRegexpDebugAPI(t *testing.T) {
	re := regexp.MustCompile(regexpDebugAPI)
	require.True(t, re.MatchString(`cluster/123/pd/dashboard/api/debug_api/aaa/bbb/ccc?aaa=aaa`))
	require.False(t, re.MatchString(`cluster/abc/pd/dashboard/api/debug_api/aaa/bbb/ccc?aaa=aaa`))
	require.False(t, re.MatchString(`/proxy/cluster/123/pd/dashboard/api/debug_api/aaa/bbb/ccc?aaa=aaa`))
}

func TestMwForbidMatchedURL(t *testing.T) {
	mwT := mwForbidMatchedURLIfNotDebugSession(func(s string) bool { return true })
	mwF := mwForbidMatchedURLIfNotDebugSession(func(s string) bool { return false })

	w := newMockResponseWriter()
	r, _ := http.NewRequest("", "", nil)
	mwT(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.FailNow(t, "request should have been forbidden but it was not")
	})).ServeHTTP(w, r)
	require.Equal(t, 403, w.statusCode)

	w = newMockResponseWriter()
	visited := false
	mwF(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { visited = true })).ServeHTTP(w, r)
	require.True(t, visited)
	require.Equal(t, 0, w.statusCode)
}

type mockResponseWriter struct {
	statusCode int
	header     http.Header
}

func newMockResponseWriter() *mockResponseWriter {
	return &mockResponseWriter{header: http.Header{}}
}

func (w *mockResponseWriter) Header() http.Header {
	return w.header
}

func (w *mockResponseWriter) Write(b []byte) (int, error) {
	return len(b), nil
}

func (w *mockResponseWriter) WriteHeader(statusCode int) {
	w.statusCode = statusCode
}
