package regionalapi

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

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

func TestBuildDMApiPath(t *testing.T) {
	tests := map[string]struct {
		apiPath string
		want    string
	}{
		"normal path": {
			apiPath: "/api/v1/tasks",
			want:    "/proxy/cluster/42/dm/dm-1/api/v1/tasks",
		},
		"deduplicates extra slash": {
			apiPath: "//api/v1/tasks",
			want:    "/proxy/cluster/42/dm/dm-1/api/v1/tasks",
		},
		"preserves query string": {
			apiPath: "//api/v1/tasks?force=true",
			want:    "/proxy/cluster/42/dm/dm-1/api/v1/tasks?force=true",
		},
		"empty path uses cluster root": {
			apiPath: "",
			want:    "/proxy/cluster/42/dm/dm-1",
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got := BuildDMApiPath("42", "dm-1", tc.apiPath)
			require.Equal(t, tc.want, got)
		})
	}
}

func TestBuildDMApiURL(t *testing.T) {
	got := BuildDMApiURL("https://gateway.example/", "42", "dm-1", "/api/v1/tasks?force=true")
	require.Equal(t, "https://gateway.example/proxy/cluster/42/dm/dm-1/api/v1/tasks?force=true", got)
}

func TestIsOperatorV2Backend(t *testing.T) {
	tests := []struct {
		backend string
		want    bool
	}{
		{"", false},
		{"legacy", false},
		{"LEGACY", false},
		{"unknown", false},
		{BackendOperatorV2, true},
		{"OPERATOR_V2", true},
		{" operator-v2 ", true},
	}
	for _, tt := range tests {
		require.Equal(t, tt.want, IsOperatorV2Backend(tt.backend))
	}
}

func TestDMOpenAPIClientBuildsGatewayRequest(t *testing.T) {
	t.Helper()

	var (
		gotMethod string
		gotPath   string
		gotAuth   string
		gotBody   []byte
	)
	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var err error
		gotMethod = r.Method
		gotPath = r.URL.RequestURI()
		gotAuth = r.Header.Get("Authorization")
		gotBody, err = io.ReadAll(r.Body)
		require.NoError(t, err)
		w.WriteHeader(http.StatusAccepted)
		_, err = w.Write([]byte(`{"ok":true}`))
		require.NoError(t, err)
	}))
	defer server.Close()

	client, err := NewDMOpenAPIClient(DMConfig{
		GatewayBaseURL: server.URL + "/",
		AuthToken:      "test-token",
		SharedPoolID:   "42",
		DMClusterID:    "dm-1",
	})
	require.NoError(t, err)

	status, respBody, err := client.Do(context.Background(), http.MethodPost, "/api/v1/tasks?force=true", []byte(`{"name":"task-1"}`))
	require.NoError(t, err)
	require.Equal(t, http.StatusAccepted, status)
	require.JSONEq(t, `{"ok":true}`, string(respBody))
	require.Equal(t, http.MethodPost, gotMethod)
	require.Equal(t, "/proxy/cluster/42/dm/dm-1/api/v1/tasks?force=true", gotPath)
	require.Equal(t, "Bearer test-token", gotAuth)
	require.JSONEq(t, `{"name":"task-1"}`, string(gotBody))
}
