package scrape

import (
	"testing"

	"github.com/pingcap/dbaas/pkg/constants"
	tidbClusterV1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
	"github.com/stretchr/testify/assert"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/billing-reporter/utils"
)

func TestIsInCreatingStatus(t *testing.T) {
	tc := &tidbClusterV1alpha1.TidbCluster{
		ObjectMeta: metav1.ObjectMeta{
			Labels: map[string]string{
				constants.TiDBClusterTenantIDLabel:         "123",
				constants.TiDBClusterClusterIDLabel:        "1",
				constants.TiDBClusterClusterProfileIDLabel: "3",
				constants.TiDBClusterStatusFromCentral:     string(constants.TidbClusterCreating),
			},
		},
	}
	m := ScrapeManager{}
	status, err := utils.IsClusterInCreatingStatus(m.kubeCli, tc)
	assert.True(t, status)
	assert.Nil(t, err)
}

func Test_checkTidbClusterStatus(t *testing.T) {
	type args struct {
		tcHeartbeatInfo *TidbClusterHeartbeatInfo
		tc              *tidbClusterV1alpha1.TidbCluster
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "none is deployed",
			args: args{
				tcHeartbeatInfo: &TidbClusterHeartbeatInfo{},
				tc:              &tidbClusterV1alpha1.TidbCluster{},
			},
			want: string(constants.TidbClusterUnavailable),
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			assert.Equal(t, tt.want, checkTidbClusterStatus(tt.args.tcHeartbeatInfo, tt.args.tc))
		})
	}
}

func Test_initTidbClusterHeartbeatInfo(t *testing.T) {
	tests := []struct {
		name    string
		tc      *tidbClusterV1alpha1.TidbCluster
		want    *TidbClusterHeartbeatInfo
		wantErr bool
	}{
		{
			name: "1 tidb, 3 tikv",
			tc: &tidbClusterV1alpha1.TidbCluster{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						constants.TiDBClusterTenantIDLabel:         "123",
						constants.TiDBClusterClusterIDLabel:        "1",
						constants.TiDBClusterClusterProfileIDLabel: "3",
					},
				},
				Spec: tidbClusterV1alpha1.TidbClusterSpec{
					TiDB: &tidbClusterV1alpha1.TiDBSpec{
						Replicas: 1,
					},
					TiKV: &tidbClusterV1alpha1.TiKVSpec{
						Replicas: 3,
					},
				},
			},
			want: &TidbClusterHeartbeatInfo{
				Tidbs: []TidbHeartbeatInfo{
					{},
				},
				Tikvs: []TikvHeartbeatInfo{
					{},
					{},
					{},
				},
			},
			wantErr: false,
		},
		{
			name: "0 tidb, 0 tikv, 0 tiflash",
			tc: &tidbClusterV1alpha1.TidbCluster{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						constants.TiDBClusterTenantIDLabel:         "123",
						constants.TiDBClusterClusterIDLabel:        "1",
						constants.TiDBClusterClusterProfileIDLabel: "3",
					},
				},
				Spec: tidbClusterV1alpha1.TidbClusterSpec{},
			},
			want:    &TidbClusterHeartbeatInfo{},
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := initTidbClusterHeartbeatInfo(tt.tc)
			if !tt.wantErr {
				assert.Nil(t, err)
				assert.Equal(t, len(tt.want.Tidbs), len(got.Tidbs))
				assert.Equal(t, len(tt.want.Tikvs), len(got.Tikvs))
				assert.Equal(t, len(tt.want.Tiflashes), len(got.Tiflashes))
			} else {
				assert.NotNil(t, err)
			}
		})
	}
}
