package task

import (
	"context"
	"fmt"
	"time"

	"github.com/go-logr/logr"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/utils"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/endpointresolver"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/repository"
)

const (
	requeueAfterDuration = time.Second * 30
)

type Context struct {
	Scheme                          *runtime.Scheme
	Local                           client.Client
	Logger                          logr.Logger
	Config                          config.RootConfig
	TmplConfig                      config.TemplatesConfig
	DataPlane                       *v1alpha1.DataPlane // optional, only used for next-gen
	OriginalDataPlaneOwnershipMode  v1alpha1.DataPlaneOwnershipMode
	DataPlaneRW                     repository.DataPlaneReaderWriter
	VpcRW                           repository.VPCReaderWriter
	InternetRW                      repository.InternetReaderWriter
	AppBoxRW                        repository.APPBoxReaderWriter
	NodePoolRW                      repository.NodePoolReaderWriter
	VpcPeeringRW                    repository.VPCPeeringReaderWriter
	PrivateLinkEndpointZoneResolver PrivateLinkEndpointZoneResolver
	BeginAt                         *time.Time
}

type PrivateLinkEndpointZoneResolver = endpointresolver.PrivateLinkEndpointZoneResolver

var _ deploy.Task = &BaseTask{}

func (c *Context) Default() (*Context, error) {
	return c, nil
}

type BaseTask struct {
	*Context
}

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

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

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()
}

func (t *BaseTask) MetricsStartTime() *time.Time {
	return t.BeginAt
}

func (t *BaseTask) GetSubResourceName() string {
	return utils.MD5(fmt.Sprintf("%s-%s",
		t.Config.ControllerConfig.RegionConfig.LogicalRegionName, t.DataPlane.Name))
}

func (t *BaseTask) GetSubResourceNamespace() string {
	return t.DataPlane.Namespace
}
