package job

import (
	"context"

	"github.com/juju/errors"
	"github.com/tidbcloud/auto-deploy/internal/constants"
	"github.com/tidbcloud/auto-deploy/internal/utils"
	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	applyv1 "k8s.io/client-go/applyconfigurations/core/v1"
	apply_rbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1"
	"k8s.io/client-go/kubernetes"
)

func ApplyDeployJobRunnerServiceAccount(clientset *kubernetes.Clientset) error {
	client := clientset.CoreV1().ServiceAccounts(apiv1.NamespaceDefault)

	sa := applyv1.ServiceAccount(constants.DEPLOY_JOB_RUNNER_SA_NAME, apiv1.NamespaceDefault)
	_, err := client.Apply(context.TODO(), sa, metav1.ApplyOptions{
		FieldManager: constants.K8S_APPLY_FIELD_MANAGER,
	})
	if err != nil {
		return errors.Annotatef(err, "Failed to apply service account: %s", constants.DEPLOY_JOB_RUNNER_SA_NAME)
	}
	return nil
}

func ApplyDeployJobRunnerServiceAccountRoleBinding(clientset *kubernetes.Clientset) error {
	client := clientset.RbacV1().ClusterRoleBindings()
	sa := apply_rbacv1.ClusterRoleBinding(constants.DEPLOY_JOB_RUNNER_SA_NAME + "-rb").WithRoleRef(&apply_rbacv1.RoleRefApplyConfiguration{
		APIGroup: utils.Ptr("rbac.authorization.k8s.io"),
		Kind:     utils.Ptr("ClusterRole"),
		Name:     utils.Ptr(constants.DEPLOY_JOB_RUNNER_CLUSTER_ROLE),
	}).WithSubjects(&apply_rbacv1.SubjectApplyConfiguration{
		Kind:      utils.Ptr("ServiceAccount"),
		Name:      utils.Ptr(constants.DEPLOY_JOB_RUNNER_SA_NAME),
		Namespace: utils.Ptr(apiv1.NamespaceDefault),
	})
	_, err := client.Apply(context.TODO(), sa, metav1.ApplyOptions{
		FieldManager: constants.K8S_APPLY_FIELD_MANAGER,
	})
	if err != nil {
		return errors.Annotatef(err, "Failed to apply service account cluster role binding: %s", constants.DEPLOY_JOB_RUNNER_SA_NAME)
	}
	return nil
}
