package models

import (
	"testing"

	dedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
)

func TestIfClusterStateNeedMetering(t *testing.T) {
	type args struct {
		state dedicatedv1.Cluster_State
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "Cluster_AVAILABLE", args: args{dedicatedv1.Cluster_AVAILABLE}, want: true},
		{name: "Cluster_SCALING", args: args{dedicatedv1.Cluster_SCALING}, want: true},
		{name: "Cluster_MODIFYING", args: args{dedicatedv1.Cluster_MODIFYING}, want: true},
		{name: "Cluster_AVAILABLE", args: args{dedicatedv1.Cluster_AVAILABLE}, want: true},
		{name: "Cluster_PAUSED", args: args{dedicatedv1.Cluster_PAUSED}, want: true},
		{name: "Cluster_PAUSING", args: args{dedicatedv1.Cluster_PAUSING}, want: true},
		{name: "Cluster_RESUMING", args: args{dedicatedv1.Cluster_RESUMING}, want: true},
		{name: "Cluster_CREATING", args: args{dedicatedv1.Cluster_CREATING}, want: false},
		{name: "Cluster_DELETED", args: args{dedicatedv1.Cluster_DELETED}, want: false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IfClusterStateNeedMetering(tt.args.state); got != tt.want {
				t.Errorf("IfClusterStateNeedMetering() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestIfComponentTypeNeedMetering(t *testing.T) {
	type args struct {
		componentType dedicatedv1.ComponentType
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "tidb", args: args{dedicatedv1.ComponentType_TIDB}, want: true},
		{name: "tikv", args: args{dedicatedv1.ComponentType_TIKV}, want: true},
		{name: "tiflash", args: args{dedicatedv1.ComponentType_TIFLASH}, want: true},
		{name: "pd", args: args{dedicatedv1.ComponentType_PD}, want: false},
		{name: "proxy", args: args{dedicatedv1.ComponentType_TIPROXY}, want: true},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IfComponentTypeNeedMetering(tt.args.componentType); got != tt.want {
				t.Errorf("IfComponentTypeNeedMetering() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestIfComponentTypeNeedMeteringForDisk(t *testing.T) {
	type args struct {
		componentType dedicatedv1.ComponentType
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "tidb", args: args{dedicatedv1.ComponentType_TIDB}, want: false},
		{name: "tikv", args: args{dedicatedv1.ComponentType_TIKV}, want: true},
		{name: "tiflash", args: args{dedicatedv1.ComponentType_TIFLASH}, want: true},
		{name: "pd", args: args{dedicatedv1.ComponentType_PD}, want: false},
		{name: "proxy", args: args{dedicatedv1.ComponentType_TIPROXY}, want: false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IfComponentTypeNeedMeteringForDisk(tt.args.componentType); got != tt.want {
				t.Errorf("IfComponentTypeNeedMeteringForDisk() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestIfNodeStateNeedMetering(t *testing.T) {
	type args struct {
		nodeState dedicatedv1.ComponentNodeInfo_Component_Node_State
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "DELETING", args: args{dedicatedv1.ComponentNodeInfo_Component_Node_DELETING}, want: true},
		{name: "AVAILABLE", args: args{dedicatedv1.ComponentNodeInfo_Component_Node_AVAILABLE}, want: true},
		{name: "UNAVAILABLE", args: args{dedicatedv1.ComponentNodeInfo_Component_Node_UNAVAILABLE}, want: true},
		{name: "CREATING", args: args{dedicatedv1.ComponentNodeInfo_Component_Node_CREATING}, want: false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IfNodeStateNeedMetering(tt.args.nodeState); got != tt.want {
				t.Errorf("IfNodeStateNeedMetering() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestIfClusterScaling(t *testing.T) {
	type args struct {
		state dedicatedv1.Cluster_State
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		{name: "scaling", args: args{dedicatedv1.Cluster_SCALING}, want: true},
		{name: "modifing", args: args{dedicatedv1.Cluster_MODIFYING}, want: true},
		{name: "creating", args: args{dedicatedv1.Cluster_CREATING}, want: false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IfClusterScaling(tt.args.state); got != tt.want {
				t.Errorf("IfClusterScaling() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestMapVolumeType(t *testing.T) {
	type args struct {
		volumeType string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "local",
			args: args{"LOCAL_STORAGE"},
			want: "local-storage",
		},
		{
			name: "GP2",
			args: args{"GP2"},
			want: "gp2",
		},
		{
			name: "GP3",
			args: args{"GP3"},
			want: "gp3",
		},
		{
			name: "IO2",
			args: args{"IO2"},
			want: "io2",
		},
		{
			name: "PD_SSD",
			args: args{"PD_SSD"},
			want: "pd-ssd",
		},
		{
			name: "PREMIUMV2",
			args: args{"PREMIUMV2"},
			want: "premiumv2",
		},
		{
			name: "ULTRASSD",
			args: args{"ULTRASSD"},
			want: "ultrassd",
		},
		{
			name: "unsupported",
			args: args{"unsupported"},
			want: "volume_type_unspecified",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := mapVolumeType(tt.args.volumeType); got != tt.want {
				t.Errorf("mapVolumeType() = %v, want %v", got, tt.want)
			}
		})
	}
}
