package awsupbound

import (
	"context"
	"fmt"

	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	ec2v1beta1 "github.com/upbound/provider-aws/apis/ec2/v1beta1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

// FindReusableVPCEndpointName tries to find a reusable vpc endpoint, so we do not need to create a new one.
// The reusable vpc endpoint should have the same service name and vpc id as given.
func FindReusableVPCEndpointName(ctx context.Context, cli client.Client, endpointType, endpointServiceName, vpcID string) (string, error) {
	endpointList := &ec2v1beta1.VPCEndpointList{}
	err := cli.List(ctx, endpointList)
	if err != nil {
		return "", fmt.Errorf("failed to list vpc endpoint: %w", err)
	}
	for i, endpoint := range endpointList.Items {
		if isVPCEndpointReusable(&endpoint, endpointType, endpointServiceName, vpcID) {
			return endpointList.Items[i].Name, nil
		}
	}
	return "", nil
}

// isVPCEndpointReusable checks whether the given vpc endpoint is reusable.
// A reusable vpc endpoint should have the same service name and vpc id as given,
// and should not be in deleting state.
func isVPCEndpointReusable(endpoint *ec2v1beta1.VPCEndpoint, endpointType, serviceName, vpcID string) bool {
	if endpoint.Spec.ForProvider.ServiceName == nil || *endpoint.Spec.ForProvider.ServiceName != serviceName {
		return false
	}
	if endpoint.Spec.ForProvider.VPCID == nil || *endpoint.Spec.ForProvider.VPCID != vpcID {
		return false
	}
	if endpoint.Spec.ForProvider.VPCEndpointType == nil || *endpoint.Spec.ForProvider.VPCEndpointType != endpointType {
		return false
	}
	// Check if not in deleting state
	condition := endpoint.Status.GetCondition(xpv1.TypeReady)
	if condition.Reason == xpv1.ReasonDeleting {
		return false
	}
	return true
}
