package api

import (
	"context"
	"errors"

	corev1 "k8s.io/api/core/v1"
)

// NamespacedResourceResolver is an abstract interface used to resolve namespaced resources
// Any implementation might exist, cache based, file based, client based etc...
type NamespacedResourceResolver[T any] interface {
	// Get is used to resolve a resource given a namespace and name
	Get(
		ctx context.Context,
		namespace string,
		name string,
	) (T, error)
}

// ConfigmapResolver is an abstract interface used to resolve configmaps
type ConfigmapResolver = NamespacedResourceResolver[*corev1.ConfigMap]

// namespacedResourceResolverChain represents a chain of NamespacedResourceResolver
type namespacedResourceResolverChain[T any] []NamespacedResourceResolver[T]

// NewNamespacedResourceResolver creates a NamespacedResourceResolver from a NamespacedResourceResolver chain
// It will try to resolve resources by iterating over individual resolvers until one finds the requested resource
func NewNamespacedResourceResolver[T any](resolvers ...NamespacedResourceResolver[T]) (NamespacedResourceResolver[T], error) {
	if len(resolvers) == 0 {
		return nil, errors.New("no resolvers")
	}
	for _, resolver := range resolvers {
		if resolver == nil {
			return nil, errors.New("at least one resolver is nil")
		}
	}
	return namespacedResourceResolverChain[T](resolvers), nil
}

func (chain namespacedResourceResolverChain[T]) Get(ctx context.Context, namespace, name string) (T, error) {
	var lastErr error
	for _, resolver := range chain {
		r, err := resolver.Get(ctx, namespace, name)
		if err == nil {
			return r, nil
		}
		lastErr = err
	}
	var notFound T
	return notFound, lastErr
}