package clustergateway

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

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

func TestListActiveDMSourceCount(t *testing.T) {
	tests := []struct {
		name       string
		statusCode int
		body       string
		want       int
		wantErr    bool
	}{
		{
			name:       "counts enabled sources",
			statusCode: http.StatusOK,
			body:       `{"total":3,"data":[{"source_name":"source-1","enable":true},{"source_name":"source-2","enable":false},{"source_name":"source-3","enable":true}]}`,
			want:       2,
		},
		{
			name:       "empty source list",
			statusCode: http.StatusOK,
			body:       `{"total":0,"data":[]}`,
			want:       0,
		},
		{
			name:       "upstream error",
			statusCode: http.StatusInternalServerError,
			body:       `{"error":"internal server error"}`,
			wantErr:    true,
		},
		{
			name:       "conflict JSON error",
			statusCode: http.StatusConflict,
			body:       `{"error":"conflict"}`,
			wantErr:    true,
		},
		{
			name:       "invalid JSON",
			statusCode: http.StatusOK,
			body:       `{`,
			wantErr:    true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				assert.Equal(t, "/proxy/cluster/shared-pool-1/dm/dm-cluster-1/api/v1/sources", r.URL.Path)
				assert.Equal(t, "Bearer test-token", r.Header.Get("Authorization"))
				w.WriteHeader(tt.statusCode)
				_, _ = w.Write([]byte(tt.body))
			}))
			defer server.Close()

			count, err := newTestClient().ListActiveDMSourceCount(
				context.Background(),
				newTestSharedPool("shared-pool-1", server.URL),
				"dm-cluster-1",
			)
			if tt.wantErr {
				require.Error(t, err)
				return
			}
			require.NoError(t, err)
			assert.Equal(t, tt.want, count)
		})
	}
}

func TestListActiveDMSourceCountTimeout(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		time.Sleep(100 * time.Millisecond)
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte(`{"total":0,"data":[]}`))
	}))
	defer server.Close()

	client := newTestClient()
	client.client.SetTimeout(10 * time.Millisecond).SetRetryCount(0)

	_, err := client.ListActiveDMSourceCount(
		context.Background(),
		newTestSharedPool("shared-pool-1", server.URL),
		"dm-cluster-1",
	)
	require.Error(t, err)
}
