package task

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestBaseTask_GetSubResourceName_Deterministic(t *testing.T) {
	bucket := &v1alpha1.Bucket{
		ObjectMeta: metav1.ObjectMeta{Name: "fallback-name"},
		Spec: v1alpha1.BucketSpec{
			DataplaneId: "dp-1",
			Id:          "bucket-1",
		},
	}
	task := &BaseTask{
		Context: &Context{
			Config: config.RootConfig{ResourceNamePrefix: "tidbcloud"},
			Bucket: bucket,
		},
	}

	firstName, err := task.GetSubResourceName()
	require.NoError(t, err)
	secondName, err := task.GetSubResourceName()
	require.NoError(t, err)

	require.Equal(t, firstName, secondName)
	require.Len(t, firstName, 63)
	require.Contains(t, firstName, "tidbcloud-")
}

func TestBaseTask_GetSubResourceName_UsesLogicalBucketIdentity(t *testing.T) {
	firstTask := &BaseTask{
		Context: &Context{
			Config: config.RootConfig{ResourceNamePrefix: "tidbcloud"},
			Bucket: &v1alpha1.Bucket{
				ObjectMeta: metav1.ObjectMeta{Name: "same-metadata-name"},
				Spec: v1alpha1.BucketSpec{
					DataplaneId: "dp-1",
					Id:          "bucket-1",
				},
			},
		},
	}
	secondTask := &BaseTask{
		Context: &Context{
			Config: config.RootConfig{ResourceNamePrefix: "tidbcloud"},
			Bucket: &v1alpha1.Bucket{
				ObjectMeta: metav1.ObjectMeta{Name: "same-metadata-name"},
				Spec: v1alpha1.BucketSpec{
					DataplaneId: "dp-1",
					Id:          "bucket-2",
				},
			},
		},
	}

	firstName, err := firstTask.GetSubResourceName()
	require.NoError(t, err)
	secondName, err := secondTask.GetSubResourceName()
	require.NoError(t, err)

	require.NotEqual(t, firstName, secondName)
}

func TestBaseTask_GetSubResourceNameAfterConflict(t *testing.T) {
	task := &BaseTask{
		Context: &Context{
			Config: config.RootConfig{ResourceNamePrefix: "tidbcloud"},
			Bucket: &v1alpha1.Bucket{
				Spec: v1alpha1.BucketSpec{
					DataplaneId: "dp-1",
					Id:          "bucket-1",
				},
			},
		},
	}

	defaultName, err := task.GetSubResourceName()
	require.NoError(t, err)
	conflictName, err := task.GetSubResourceNameAfterConflict(defaultName)
	require.NoError(t, err)
	secondConflictName, err := task.GetSubResourceNameAfterConflict(defaultName)
	require.NoError(t, err)

	require.NotEqual(t, defaultName, conflictName)
	require.Equal(t, conflictName, secondConflictName)
	require.Len(t, conflictName, 63)
}

func TestBaseTask_GetCurrentOrSubResourceName(t *testing.T) {
	task := &BaseTask{
		Context: &Context{
			Config: config.RootConfig{ResourceNamePrefix: "tidbcloud"},
			Bucket: &v1alpha1.Bucket{
				Spec: v1alpha1.BucketSpec{
					DataplaneId: "dp-1",
					Id:          "bucket-1",
				},
				Status: v1alpha1.BucketStatus{
					Bucket: &v1alpha1.Reference{Name: "current-bucket"},
				},
			},
		},
	}

	name, err := task.GetCurrentOrSubResourceName()
	require.NoError(t, err)

	require.Equal(t, "current-bucket", name)
}
