package common

import (
	"context"
	"fmt"

	rbacv1 "k8s.io/api/rbac/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/k8s"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"
)

// ClusterRole is a task to create additional ClusterRoles or ClusterRoleBindings
type ClusterRole struct {
	*task.BaseTask
}

func NewClusterRole(ctx *task.Context) *ClusterRole {
	return &ClusterRole{
		BaseTask: &task.BaseTask{Context: ctx},
	}
}

func (s *ClusterRole) Name() string {
	return "ClusterRole"
}

// Create schedule an account and update the account reference for a network.
func (s *ClusterRole) Create(ctx context.Context) deploy.Result {
	cli, err := s.Remote.GetClient(ctx)
	if err != nil {
		return deploy.Panic(err)
	}

	clusterViewerRole := &rbacv1.ClusterRole{
		ObjectMeta: metav1.ObjectMeta{
			Name: consts.ClusterRoleViewerName,
		},
		Rules: []rbacv1.PolicyRule{
			{
				Verbs:     []string{"get", "list", "watch"},
				APIGroups: []string{rbacv1.APIGroupAll},
				Resources: []string{rbacv1.ResourceAll},
			},
		},
	}
	if err := k8s.Apply(ctx, cli, clusterViewerRole); err != nil {
		return deploy.Error(fmt.Errorf("create cluster-viewer clusterRole: %w", err))
	}

	return deploy.Done()
}
