package resourcemanager

import (
	"context"
	"testing"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"

	"github.com/stretchr/testify/assert"
)

func newConfigMapClient(t *testing.T) client.Client {
	scheme := runtime.NewScheme()
	assert.NoError(t, corev1.AddToScheme(scheme))
	return fake.NewClientBuilder().WithScheme(scheme).Build()
}

func Test_ConfigMap_Create_Get_Update(t *testing.T) {
	cli := newConfigMapClient(t)
	rw := configMapReaderWriter{cli: cli}

	cm := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: "ns1", Name: "cm1", Labels: map[string]string{"l1": "v1"}}, Data: map[string]string{"k": "v"}}
	err := rw.Create(context.TODO(), cm)
	assert.NoError(t, err)

	got, err := rw.Get(context.TODO(), "ns1", "cm1")
	assert.NoError(t, err)
	assert.Equal(t, "v", got.Data["k"])
	assert.Equal(t, "v1", got.Labels["l1"])

	got.Data["k"] = "v2"
	got.Labels["l1"] = "v2"
	err = rw.Update(context.TODO(), got)
	assert.NoError(t, err)

	got2, err := rw.Get(context.TODO(), "ns1", "cm1")
	assert.NoError(t, err)
	assert.Equal(t, "v2", got2.Data["k"])
	assert.Equal(t, "v2", got2.Labels["l1"])
}

func Test_ConfigMap_Get_NotFound(t *testing.T) {
	cli := newConfigMapClient(t)
	rw := configMapReaderWriter{cli: cli}
	_, err := rw.Get(context.TODO(), "ns2", "missing")
	assert.Error(t, err)
}

func Test_ConfigMap_CreateOrUpdate(t *testing.T) {
	cli := newConfigMapClient(t)
	rw := configMapReaderWriter{cli: cli}

	existing := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: "ns3", Name: "cm2", Labels: map[string]string{"a": "1"}}, Data: map[string]string{"x": "1"}}
	assert.NoError(t, cli.Create(context.TODO(), existing))

	desired := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: "ns3", Name: "cm2", Labels: map[string]string{"a": "2", "b": "3"}}, Data: map[string]string{"x": "9", "y": "10"}}
	err := rw.CreateOrUpdate(context.TODO(), desired)
	assert.NoError(t, err)

	got, err := rw.Get(context.TODO(), "ns3", "cm2")
	assert.NoError(t, err)
	assert.Equal(t, "9", got.Data["x"])
	assert.Equal(t, "10", got.Data["y"])
	assert.Equal(t, "2", got.Labels["a"])
	assert.Equal(t, "3", got.Labels["b"])
}
