package task

import (
	"context"
	"errors"
	"fmt"

	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"sigs.k8s.io/controller-runtime/pkg/client"

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/deploy"
)

type VPCPeering struct {
	*BaseTask
}

func NewVPCPeering(ctx *Context) *VPCPeering {
	return &VPCPeering{BaseTask: &BaseTask{Context: ctx}}
}

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

func (t *VPCPeering) Delete(ctx context.Context) deploy.Result {
	vpcPeerings := new(v1alpha1.VPCPeeringList)
	if err := t.VpcPeeringRW.List(ctx, vpcPeerings, t.listOptions()...); err != nil {
		return deploy.Panic(err).WithRequeuAfter(requeueAfterDuration)
	}

	var errs []error
	for i := range vpcPeerings.Items {
		if err := t.VpcPeeringRW.Delete(ctx, &vpcPeerings.Items[i]); err != nil && !apierrors.IsNotFound(err) {
			errs = append(errs, err)
		}
	}
	if len(errs) > 0 {
		return deploy.Panic(errors.Join(errs...)).WithRequeuAfter(requeueAfterDuration)
	}
	return deploy.Done()
}

func (t *VPCPeering) PostDelete(ctx context.Context) deploy.Result {
	vpcPeerings := new(v1alpha1.VPCPeeringList)
	if err := t.VpcPeeringRW.List(ctx, vpcPeerings, t.listOptions()...); err != nil {
		return deploy.Error(err).WithRequeuAfter(requeueAfterDuration)
	}
	if len(vpcPeerings.Items) > 0 {
		return deploy.Error(fmt.Errorf("vpcpeering crs not deleted: %d remaining", len(vpcPeerings.Items))).
			WithRequeuAfter(requeueAfterDuration)
	}
	return deploy.Done()
}

func (t *VPCPeering) listOptions() []client.ListOption {
	return []client.ListOption{
		client.InNamespace(t.DataPlane.Namespace),
		client.MatchingLabels{v1alpha1.DataPlaneIDKey: t.DataPlane.Name},
	}
}
