package ack

import (
	"context"
	"fmt"

	ackv1alpha1 "github.com/crossplane-contrib/provider-upjet-alibabacloud/apis/ack/v1alpha1"
	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	o11yv2 "github.com/tidbcloud/observability/agent-control-server/api/v2"
	"k8s.io/apimachinery/pkg/types"

	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task/common"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/namer"
)

// Provider implementation resides in the ack package to keep common free from cloud-specific deps.
type ackProvider struct{}

func (ackProvider) FillProviderSpec(ctx context.Context, t *task.BaseTask, spec *o11yv2.KubernetesAgentSpec) error {
	key := types.NamespacedName{
		Name: controllers.UniqueIdentifier(t.APPBox.ObjectMeta, namer.WithPrefix(t.Config.ResourceNamePrefix)),
	}
	ackCluster := &ackv1alpha1.ManagedKubernetes{}
	if err := t.Local.Get(ctx, key, ackCluster); err != nil {
		return err
	}
	sg := ackCluster.Status.AtProvider.SecurityGroupID
	if sg == nil {
		return fmt.Errorf("ack cluster %s has no security group", ackCluster.Name)
	}
	spec.ACK = &o11yv2.ACKConfig{
		AccountID:               t.VPC.Spec.AccountRef.AccountID,
		AssumeRoleArn:           t.RoleARN(),
		VpcID:                   t.VPC.Status.VPC.VPCID,
		SecurityGroupID:         *sg,
		ProviderConfigReference: &xpv1.Reference{Name: t.VPC.Spec.AccountRef.ProviderConfigName},
	}
	return nil
}

// NewO11yProvider returns the ACK provider implementation for common O11y task.
func NewO11yProvider() common.Provider { return ackProvider{} }
