package task

import (
	"context"
	"time"

	ec2v1beta1 "github.com/crossplane-contrib/provider-aws/apis/ec2/v1beta1"
	"github.com/go-logr/logr"
	"sigs.k8s.io/controller-runtime/pkg/client"

	"github.com/tidbcloud/eks-provider/api/v1alpha1"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/config"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/namer"
)

const Finalizer = "cluster.cloud.pingcap.com/finalizer"

type Context struct {
	// Transient during a deployment
	namer *namer.Namer

	// Injected from the caller
	Logger      logr.Logger
	Subnets     []*ec2v1beta1.Subnet
	Local       client.Client
	PLEndpoint  *v1alpha1.PrivateLinkEndpoint
	Network     *cloudv1.Network
	Kubernetes  *cloudv1.Kubernetes
	NetworkSpec *v1alpha1.EKSNetworkSpec
	Config      config.RootConfig

	// BeginAt denotes the starting time of the task.
	BeginAt *time.Time
}

func (c *Context) Default() *Context {
	c.namer = namer.NewNamer()
	return c
}

func (c *Context) GetAKSProviderConfigName() string {
	// pc-{k8s-network-name}-{hash}-plendpoint
	// all privatelink resources in the same AKS share the same provider config
	return namer.NewName(c.PLEndpoint.K8sNetworkName(), "pc", "plendpoint", -1)
}

var _ deploy.Task = &BaseTask{}

type BaseTask struct {
	*Context
}

func (t *BaseTask) Name() string {
	return ""
}

func (t *BaseTask) Category() deploy.TaskCategory {
	return deploy.PrivateLinkEndpointTask
}

func (t *BaseTask) Create(ctx context.Context) deploy.Result {
	return deploy.Done()
}

func (t *BaseTask) PostCreate(ctx context.Context) deploy.Result {
	return deploy.Done()
}

func (t *BaseTask) Delete(ctx context.Context) deploy.Result {
	return deploy.Done()
}

func (t *BaseTask) PostDelete(ctx context.Context) deploy.Result {
	return deploy.Done()
}

// MetricsStartTime will return the `BeginAt` (nil by default). For
// Task whose metrics need to be exported, the `BeginAt` should be
// initialized when the `Create` is being called.
func (t *BaseTask) MetricsStartTime() *time.Time {
	return t.Context.BeginAt
}
