package service

import (
	"testing"

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

func Test_calcNextOrdinalForComponent(t *testing.T) {
	type args struct {
		replicas     int32
		deletedSlots []int32
	}
	tests := []struct {
		name                string
		args                args
		wantCurrentOrdinals []int32
		wantNextOrdinal     int32
	}{
		{
			name: "deletedSlots is empty",
			args: args{
				replicas:     3,
				deletedSlots: nil,
			},
			wantCurrentOrdinals: []int32{0, 1, 2},
			wantNextOrdinal:     3,
		},
		{
			name: "deletedSlots is non-empty and the length is less than replicas",
			args: args{
				replicas:     3,
				deletedSlots: []int32{0, 2},
			},
			wantCurrentOrdinals: []int32{1, 3, 4},
			wantNextOrdinal:     5,
		},
		{
			name: "deletedSlots is non-empty and the length is more than replicas",
			args: args{
				replicas:     3,
				deletedSlots: []int32{0, 2, 3, 5},
			},
			wantCurrentOrdinals: []int32{1, 4, 6},
			wantNextOrdinal:     7,
		},
		{
			name: "all deletedSlots are greater than replicas",
			args: args{
				replicas:     3,
				deletedSlots: []int32{5, 7},
			},
			wantCurrentOrdinals: []int32{0, 1, 2},
			wantNextOrdinal:     3,
		}, {
			name: "all deletedSlots are greater than replicas and deletedSlots is continuous with currentOrdinals",
			args: args{
				replicas:     3,
				deletedSlots: []int32{3, 4},
			},
			wantCurrentOrdinals: []int32{0, 1, 2},
			wantNextOrdinal:     5,
		}, {
			name: "all deletedSlots are greater than replicas and deletedSlots is continuous with currentOrdinals and have a middle slot",
			args: args{
				replicas:     3,
				deletedSlots: []int32{3, 5},
			},
			wantCurrentOrdinals: []int32{0, 1, 2},
			wantNextOrdinal:     4,
		},
		{
			name: "replicas is zero",
			args: args{
				replicas:     0,
				deletedSlots: []int32{5, 7},
			},
			wantCurrentOrdinals: nil,
			wantNextOrdinal:     0,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			currentOrdinals, nextOrdinal := calcNextOrdinal(tt.args.replicas, tt.args.deletedSlots)
			assert.Equalf(t, tt.wantCurrentOrdinals, currentOrdinals, "currentOrdinals")
			assert.Equalf(t, tt.wantNextOrdinal, nextOrdinal, "nextOrdinal")
		})
	}
}
