package resourcemanager

import (
	"context"

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

type configMapReaderWriter struct {
	cli client.Client
}

func (c configMapReaderWriter) Get(ctx context.Context, namespace, name string) (*corev1.ConfigMap, error) {
	configMap := &corev1.ConfigMap{}
	err := c.cli.Get(ctx, types.NamespacedName{
		Namespace: namespace,
		Name:      name,
	}, configMap)
	if err != nil {
		return nil, WrapClientError(err)
	}
	return configMap, nil
}

func (c configMapReaderWriter) Create(ctx context.Context, configMap *corev1.ConfigMap) error {
	err := c.cli.Create(ctx, configMap)
	if err != nil {
		return WrapClientError(err)
	}
	return nil
}

func (c configMapReaderWriter) Update(ctx context.Context, configMap *corev1.ConfigMap) error {
	err := c.cli.Update(ctx, configMap)
	if err != nil {
		return WrapClientError(err)
	}
	return nil
}

func (c configMapReaderWriter) CreateOrUpdate(ctx context.Context, configMap *corev1.ConfigMap) error {
	// Store the desired state from the input configMap
	desiredData := make(map[string]string)
	for k, v := range configMap.Data {
		desiredData[k] = v
	}
	desiredLabels := make(map[string]string)
	for k, v := range configMap.Labels {
		desiredLabels[k] = v
	}

	_, err := controllerutil.CreateOrUpdate(ctx, c.cli, configMap, func() error {
		// Apply the desired state in the mutate function
		if configMap.Data == nil {
			configMap.Data = make(map[string]string)
		}
		for k, v := range desiredData {
			configMap.Data[k] = v
		}

		if configMap.Labels == nil {
			configMap.Labels = make(map[string]string)
		}
		for k, v := range desiredLabels {
			configMap.Labels[k] = v
		}

		return nil
	})
	return WrapClientError(err)
}
