package gke

import (
	"context"

	"github.com/tidbcloud/infra-provider/pkg/cloud/gcp"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/internet/task"
)

// GoogleApiPsc is the task to create/delete the google api private service connection.
// For the 3-layer arch, we don't need to create the PSC because we have enabled private Google access.
// For the migrated VPC, the PSC has been created by the cloud-native arch, and we need to delete it when deleting the internet.
type GoogleApiPsc struct {
	*task.BaseTask
	gcpCli gcp.Client
}

var _ deploy.Task = &GoogleApiPsc{}

func NewGoogleApiPsc(ctx *task.Context, gcpCli gcp.Client) *GoogleApiPsc {
	return &GoogleApiPsc{
		BaseTask: &task.BaseTask{Context: ctx},
		gcpCli:   gcpCli,
	}
}

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

func (t *GoogleApiPsc) Create(ctx context.Context) deploy.Result {
	project := t.VPC.Spec.AccountRef.AccountID
	network := t.VPC.Status.VPC.VPCID

	// If the VPC is legacy, represent the vpc is migrated from the cloudnative arch.
	if t.VPCIsLegacy() {
		exists, err := t.gcpCli.IsGoogleApiPscExists(ctx, project, network)
		if err != nil {
			return deploy.Error(err)
		}
		// if the PSC exists, return directly.
		if exists {
			return deploy.Done()
		}
		// for new vpc, we have enable private google access, so we don't need to create PSC.
		// In some cases, the PSC does not exist but the PSC DNS zone exists.
		// The existing PSC DNS zone will block the network access to Google API on Gke, so we also need to delete the PSC DNS zone.
		t.Logger.Info("Try to delete the google api psc dns zone")
		if err := t.gcpCli.DeleteGoogleApiPscDnsZone(ctx, project); err != nil {
			return deploy.Error(err)
		}
	}

	return deploy.Done()
}

func (t *GoogleApiPsc) Delete(ctx context.Context) deploy.Result {
	project := t.VPC.Spec.AccountRef.AccountID
	network := t.VPC.Status.VPC.VPCID
	if t.VPCIsLegacy() {
		// If the vpc is legacy, represent the vpc is migrated from the cloudnative arch.
		// In this case, we need to delete the all google api psc.
		t.Logger.Info("Try to delete all google api psc")
		if err := t.gcpCli.DeleteAllGoogleApiPsc(ctx, project, network); err != nil {
			return deploy.Error(err)
		}
	}
	return deploy.Done()
}
