package gke

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/eks-provider/controllers/network/task"
	"github.com/tidbcloud/infra-provider/pkg/cloud/gcp"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/util"
)

const roleArtifactRegistryReader = "roles/artifactregistry.reader"

// ArtifactRegistryPolicy grant permissions to node SA at the project level,
// so that the node can pull images from the Artifact Registry.
// refer to https://cloud.google.com/artifact-registry/docs/access-control#grant
type ArtifactRegistryPolicy struct {
	*task.BaseTask
	gcpCli gcp.Client
}

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

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

func (t *ArtifactRegistryPolicy) Create(ctx context.Context) deploy.Result {
	t.BeginAt = util.Pointer(time.Now())
	centralProjectID := t.Config.FullManage.GCPProjectID
	saEmail := t.Network.Status.IAM.ServiceAccountEmail
	if saEmail == "" {
		return deploy.Error(fmt.Errorf("service account is empty"))
	}

	if err := t.gcpCli.ResourceManager().AddProjectPolicyBinding(
		ctx,
		centralProjectID,
		roleArtifactRegistryReader,
		serviceAccountPrefix+saEmail,
	); err != nil {
		return deploy.Error(err)
	}

	return deploy.Done()
}

func (t *ArtifactRegistryPolicy) Delete(ctx context.Context) deploy.Result {
	saEmail := t.Network.Status.IAM.ServiceAccountEmail
	if saEmail == "" { // skip if service account is not created
		return deploy.Done()
	}
	centralProjectID := t.Config.FullManage.GCPProjectID
	if err := t.gcpCli.ResourceManager().DelProjectPolicyBinding(
		ctx,
		centralProjectID,
		roleArtifactRegistryReader,
		serviceAccountPrefix+saEmail,
	); err != nil {
		return deploy.Error(err)
	}
	return deploy.Done()
}
