package eks_test

import (
	"context"
	"testing"

	"github.com/go-logr/logr"
	"github.com/stretchr/testify/require"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/utils/pointer"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
	"sigs.k8s.io/yaml"

	ec2v1alpha1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1alpha1"
	eksv1beta1 "github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"
	taskeks "github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task/eks"
	rmgrappbox "github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/appbox"
	rmgrvpc "github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/vpc"
	"github.com/tidbcloud/infra-provider/regional-server/test/testdata"
)

func TestIsSafeToApplyEKS(t *testing.T) {
	s := runtime.NewScheme()
	require.Nil(t, v1alpha1.SchemeBuilder.AddToScheme(s))
	require.Nil(t, ec2v1alpha1.SchemeBuilder.AddToScheme(s))
	require.Nil(t, eksv1beta1.SchemeBuilder.AddToScheme(s))

	config, err := config.LoadRootConfig("../../../../../examples/root-config-eks.yaml")
	require.Nil(t, err)
	defaultAPPBox := new(v1alpha1.APPBox)
	defaultVPC := new(v1alpha1.VPC)
	{
		bs, err := testdata.LoadEKSAPPBoxYAML()
		require.NoError(t, err)
		require.NoError(t, yaml.Unmarshal(bs, defaultAPPBox))
	}
	{
		bs, err := testdata.LoadEKSVPCYAML()
		require.NoError(t, err)
		require.NoError(t, yaml.Unmarshal(bs, defaultVPC))
	}
	{
		appbox := defaultAPPBox.DeepCopy()
		vpc := defaultVPC.DeepCopy()
		kubeClient := fake.NewClientBuilder().WithScheme(s).WithObjects(vpc, appbox).WithStatusSubresource(vpc, appbox).Build()
		c, err := (&task.Context{
			Local:    kubeClient,
			Config:   config,
			VPC:      vpc,
			APPBox:   appbox,
			Logger:   logr.Discard(),
			APPBoxRW: rmgrappbox.NewAPPBoxReaderWriter(kubeClient),
			VPCR:     rmgrvpc.NewVPCReader(kubeClient),
		}).Default()
		require.Nil(t, err)
		// for now we do not have a way to mock aws.Client properly.
		eksTask := taskeks.NewEKS(c, nil)
		cluster, err := eksTask.BuildEKS(context.Background())
		require.Nil(t, err)
		{
			ok, err := eksTask.IsSafeToApplyEKS(context.Background(), cluster)
			require.Nil(t, err)
			require.True(t, ok)
		}
		{
			// IsSafeToApplyEKS does not check status, label and annotation
			cluster.Status.AtProvider.Version = "1.28.0"
			if cluster.Annotations == nil {
				cluster.Annotations = map[string]string{}
			}
			if cluster.Labels == nil {
				cluster.Labels = map[string]string{}
			}
			cluster.Annotations["foo"] = "foo"
			cluster.Labels["foo"] = "foo"
			ok, err := eksTask.IsSafeToApplyEKS(context.Background(), cluster)
			require.Nil(t, err)
			require.True(t, ok)
		}
		{
			// IsSafeToApplyEKS does not check status, label and annotation
			cluster.Spec.ForProvider.Version = pointer.String("1.28.0")
			ok, err := eksTask.IsSafeToApplyEKS(context.Background(), cluster)
			require.Nil(t, err)
			require.False(t, ok)
		}
	}
}
