package task

import (
	"context"
	"time"

	"github.com/go-logr/logr"
	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/namer"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/azure"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/clustercli"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/privatelinkservice"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/resourcemanager/vpc"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

type Context struct {
	Local                client.Client
	Logger               logr.Logger
	BeginAt              *time.Time
	Namer                *namer.Namer
	VPC                  *v1alpha1.VPC
	VPCR                 vpc.VPCReader
	PrivateLinkService   *v1alpha1.PrivateLinkService
	PrivateLinkServiceRW privatelinkservice.PrivateLinkServiceReaderWriter
	Config               config.RootConfig
	ClusterCli           clustercli.ClusterClient

	// Provider specific
	PLSCli azure.PrivateLinkServiceClient
}

var _ deploy.Task = &BaseTask{}

func (c *Context) Default() (*Context, error) {
	// Use vpc name and namespace as the network name and namespace
	// to ensure compatibility
	c.Namer = namer.NewNamer().
		LegacyWithNetworkName(c.PrivateLinkService.Name).
		LegacyWithNetworkNamespace(c.PrivateLinkService.Namespace)

	switch c.Config.Provider {
	case consts.ProviderTypeAKS:
		subscriptionID := c.GetSubscriptionID()
		plsCli, err := azure.NewPrivateLinkServiceClient(subscriptionID)
		if err != nil {
			return nil, err
		}
		c.PLSCli = plsCli
	default:
	}
	return c, nil
}

func (c *Context) GetSubscriptionID() string {
	if c.VPC.Spec.AccountRef != nil {
		return c.VPC.Spec.AccountRef.AccountID
	}
	return ""
}

func (c *Context) ProviderConfigName() string {
	if c.VPC.Spec.AccountRef != nil {
		return c.VPC.Spec.AccountRef.ProviderConfigName
	}
	return ""
}

func (c *Context) RoleARN() string {
	if c.VPC.Spec.AccountRef != nil {
		return "arn:aws:iam::" + c.VPC.Spec.AccountRef.AccountID + ":role/" + c.VPC.Spec.AccountRef.Role
	}
	return ""
}

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
}
