package controller

import (
	"context"
	"errors"
	"fmt"

	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/yaml"
)

// Destination is a resolved backup target parsed from the operator's
// destinations ConfigMap.
type Destination struct {
	PlacementTarget  string `json:"placementTarget,omitempty"`
	Zonegroup        string `json:"zonegroup,omitempty"`
	Endpoint         string `json:"endpoint,omitempty"`
	EndpointCASecret string `json:"endpointCASecret,omitempty"`
	EndpointCAKey    string `json:"endpointCAKey,omitempty"`
}

// errDestinationNotFound signals a missing ConfigMap or entry so callers can
// emit a Warning event and requeue instead of treating it as a hard failure.
var errDestinationNotFound = errors.New("destination not found")

// resolveDestination looks a logical destination name up in the operator's
// destinations ConfigMap and parses its YAML entry.
func resolveDestination(ctx context.Context, c client.Client, ns, cmName, dest string) (Destination, error) {
	var cm corev1.ConfigMap
	if err := c.Get(ctx, types.NamespacedName{Namespace: ns, Name: cmName}, &cm); err != nil {
		if apierrors.IsNotFound(err) {
			return Destination{}, fmt.Errorf("destinations ConfigMap %s/%s: %w", ns, cmName, errDestinationNotFound)
		}
		return Destination{}, err
	}
	raw, ok := cm.Data[dest]
	if !ok {
		return Destination{}, fmt.Errorf("destination %q: %w", dest, errDestinationNotFound)
	}
	var d Destination
	if err := yaml.Unmarshal([]byte(raw), &d); err != nil {
		return Destination{}, fmt.Errorf("destination %q: %w", dest, err)
	}
	if d.Endpoint == "" {
		return Destination{}, fmt.Errorf("destination %q: missing endpoint", dest)
	}
	return d, nil
}
