package regionalserver

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

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	clusterngv1beta "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"google.golang.org/grpc/codes"

	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func TestListNodeSpecs(t *testing.T) {
	t.Parallel()

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
		assert.Equal(t, http.MethodGet, request.Method)
		assert.Equal(t, "/api/premium/v1/nodeSpecs", request.URL.Path)
		assert.Equal(t, "TIFLASH_COMPUTE", request.URL.Query().Get("componentType"))
		assert.Equal(t, "42", request.URL.Query().Get("tenantId"))
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`{
			"nodeSpecOptions":[{
				"nodeSpec":{"cpu":8,"memoryGi":32},
				"storageOptions":[{
					"name":"DATA",
					"medium":"STORAGE_MEDIUM_CLOUD",
					"defaultSizeGi":600,
					"minSizeGi":200,
					"maxSizeGi":5000
				}]
			}],
			"nodeCountOptions":{
				"defaultNodeCount":1,
				"minNodeCount":1,
				"maxNodeCount":1,
				"rule":{"type":"NODE_COUNT_RULE_TYPE_FIXED","value":1}
			}
		}`))
	}))
	defer server.Close()

	response, err := newTestRegionalCli().ListNodeSpecs(
		context.Background(),
		newActiveRegion(server.URL),
		&clusterngv1beta.ListNodeSpecsRequest{
			ComponentType: clusterngv1beta.ComponentType_TIFLASH_COMPUTE,
			TenantId:      "42",
		},
	)
	require.Nil(t, err)
	require.Len(t, response.GetNodeSpecOptions(), 1)
	require.EqualValues(t, 8, response.GetNodeSpecOptions()[0].GetNodeSpec().GetCpu())
	require.EqualValues(t, 600, response.GetNodeSpecOptions()[0].GetStorageOptions()[0].GetDefaultSizeGi())
	require.Equal(t, clusterngv1beta.NodeCountRuleType_NODE_COUNT_RULE_TYPE_FIXED,
		response.GetNodeCountOptions().GetRule().GetType())
}

func TestListNodeSpecs_UnimplementedIsUnavailable(t *testing.T) {
	t.Parallel()

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		http.Error(w, `{"code":12,"message":"not implemented"}`, http.StatusNotImplemented)
	}))
	defer server.Close()

	_, err := newTestRegionalCli().ListNodeSpecs(
		context.Background(),
		newActiveRegion(server.URL),
		&clusterngv1beta.ListNodeSpecsRequest{
			ComponentType: clusterngv1beta.ComponentType_TIKV,
			TenantId:      "42",
		},
	)
	require.NotNil(t, err)
	require.Equal(t, bizerr.ErrCode(codes.Unavailable), err.ErrCode())
}
