package bucket

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/bucket/task"
	"github.com/tidbcloud/infra-provider/regional-server/test/kubemock"
	"go.uber.org/mock/gomock"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/utils/ptr"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

func TestBucketQueryer_GetDataplanePermissionStatus(t *testing.T) {
	tests := []struct {
		name                                    string
		namespace                               string
		bucketName                              string
		dpid                                    string
		setupMock                               func(*kubemock.MockClient)
		expectedBucketDataplanePermissionStatus *task.BucketDataplanePermissionStatus
		expectedError                           bool
		errorContains                           string
	}{
		{
			name:       "Dataplane Permission Not Found - Returns NotExists",
			namespace:  "default",
			bucketName: "test-bucket",
			dpid:       "dp-123",
			setupMock: func(mockClient *kubemock.MockClient) {
				// Mock bucket with no granted dataplane IDs
				bucket := &v1alpha1.Bucket{
					ObjectMeta: metav1.ObjectMeta{
						Name:      "test-bucket",
						Namespace: "default",
					},
					Spec: v1alpha1.BucketSpec{
						DataplaneId:         "dp-owner",
						GrantedDataplaneIds: []string{},
					},
				}
				mockClient.EXPECT().Get(gomock.Any(), types.NamespacedName{
					Namespace: "default",
					Name:      "test-bucket",
				}, gomock.Any()).Do(func(ctx context.Context, key types.NamespacedName, obj client.Object, opts ...client.GetOption) {
					b := obj.(*v1alpha1.Bucket)
					*b = *bucket
				}).Return(nil)
			},
			expectedBucketDataplanePermissionStatus: ptr.To(task.BucketDataplanePermissionStatusNotExists),
			expectedError:                           false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ctrl := gomock.NewController(t)
			defer ctrl.Finish()

			mockClient := kubemock.NewMockClient(ctrl)
			tt.setupMock(mockClient)

			queryer := NewBucketQueryer(mockClient)
			permissionStatus, err := queryer.GetDataplanePermissionStatus(context.Background(), tt.namespace, tt.bucketName, tt.dpid)

			if tt.expectedError {
				assert.Error(t, err)
				if tt.errorContains != "" {
					assert.Contains(t, err.Error(), tt.errorContains)
				}
			} else {
				assert.NoError(t, err)
				assert.Equal(t, tt.expectedBucketDataplanePermissionStatus, permissionStatus)
			}
		})
	}
}
