package cmek

import (
	"math/rand/v2"
	"testing"
	"unicode"

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

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func Test_generateCmekKeySuffix(t *testing.T) {
	for range 1000 {
		suffix, err := generateCmekKeySuffix(rand.Uint64())
		require.NoError(t, err)
		assert.Len(t, suffix.Suffix, 16)
		assert.True(t, isAlphanumeric(suffix.Suffix))
	}
}

func isAlphanumeric(s string) bool {
	for _, r := range s {
		if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
			return false
		}
	}
	return true
}

func Test_verifyCmekKeySuffix(t *testing.T) {
	type args struct {
		projectId   uint64
		keyVaultKey string
		suffixEn    *entity.ProjectCmekKeySuffix
	}
	tests := []struct {
		name  string
		args  args
		want  bool
		want1 bizerr.BizError
	}{
		{
			"matched",
			args{
				projectId:   1111,
				keyVaultKey: "aaaaa-bbbbbbbbbbbbbbbb",
				suffixEn:    &entity.ProjectCmekKeySuffix{ProjectId: 1111, Suffix: "bbbbbbbbbbbbbbbb"},
			},
			true,
			nil,
		},
		{
			"unmatched projectId",
			args{
				projectId:   2222,
				keyVaultKey: "aaaaa-bbbbbbbbbbbbbbbb",
				suffixEn:    &entity.ProjectCmekKeySuffix{ProjectId: 1111, Suffix: "bbbbbbbbbbbbbbbb"},
			},
			false,
			nil,
		},
		{
			"unmatched key",
			args{
				projectId:   1111,
				keyVaultKey: "aaaaa-cccccccccccccccc",
				suffixEn:    &entity.ProjectCmekKeySuffix{ProjectId: 1111, Suffix: "bbbbbbbbbbbbbbbb"},
			},
			false,
			nil,
		},
		{
			"not found",
			args{projectId: 1111, keyVaultKey: "aaaaa-bbbbbbbbbbbbbbbb", suffixEn: nil},
			false,
			bizerr.New(bizerr.ErrCodeParams, "cmek suffix not found"),
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, got1 := verifyCmekKeySuffix(tt.args.projectId, tt.args.keyVaultKey, tt.args.suffixEn)
			if got != tt.want {
				t.Errorf("verifyCmekKeySuffix() got = %v, want %v", got, tt.want)
			}

			if tt.want1 == nil && got1 != nil {
				t.Errorf("verifyCmekKeySuffix() got1 = %v, want nil", got1)
				return
			}
			if tt.want1 != nil && got1 == nil {
				t.Errorf("verifyCmekKeySuffix() got1 = nil, want %v", tt.want1)
				return
			}
			if tt.want1 != nil && got1 != nil && got1.ErrCode() != tt.want1.ErrCode() {
				t.Errorf("verifyCmekKeySuffix() got1 = %v, want %v", got1, tt.want1)
			}
		})
	}
}
