package virtualmachine

import (
	"context"
	"testing"

	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"
	ctrl "sigs.k8s.io/controller-runtime"

	proxmoxv1alpha1 "github.com/sankofa/crossplane-provider-proxmox/apis/v1alpha1"
)

func TestProxmoxVMReconciler_Reconcile(t *testing.T) {
	tests := []struct {
		name    string
		vm      *proxmoxv1alpha1.ProxmoxVM
		wantErr bool
	}{
		{
			name: "valid VM",
			vm: &proxmoxv1alpha1.ProxmoxVM{
				ObjectMeta: metav1.ObjectMeta{
					Name:      "test-vm",
					Namespace: "default",
				},
				Spec: proxmoxv1alpha1.ProxmoxVMSpec{
					ForProvider: proxmoxv1alpha1.ProxmoxVMParameters{
						Node:    "pve1",
						Name:    "test-vm",
						CPU:     2,
						Memory:  "4Gi",
						Disk:    "50Gi",
						Storage: "local-lvm",
						Network: "vmbr0",
						Image:   "ubuntu-22.04-cloud",
						Site:    "us-sfvalley",
					},
					ProviderConfigReference: &proxmoxv1alpha1.ProviderConfigReference{
						Name: "test-provider-config",
					},
				},
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			scheme := runtime.NewScheme()
			_ = proxmoxv1alpha1.AddToScheme(scheme)

			fakeClient := fake.NewClientBuilder().
				WithScheme(scheme).
				WithObjects(tt.vm).
				Build()

			r := &ProxmoxVMReconciler{
				Client: fakeClient,
				Scheme: scheme,
			}

			ctx := context.Background()
			req := ctrl.Request{
				NamespacedName: client.ObjectKeyFromObject(tt.vm),
			}

			_, err := r.Reconcile(ctx, req)
			if (err != nil) != tt.wantErr {
				t.Errorf("Reconcile() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

func TestProxmoxVMReconciler_getCredentials(t *testing.T) {
	tests := []struct {
		name           string
		providerConfig *proxmoxv1alpha1.ProviderConfig
		wantErr        bool
	}{
		{
			name: "missing secret reference",
			providerConfig: &proxmoxv1alpha1.ProviderConfig{
				ObjectMeta: metav1.ObjectMeta{
					Name: "test-config",
				},
				Spec: proxmoxv1alpha1.ProviderConfigSpec{
					Credentials: proxmoxv1alpha1.CredentialsSource{
						Source: "Secret",
						SecretRef: &proxmoxv1alpha1.SecretKeySelector{
							Name:      "test-secret",
							Namespace: "default",
							Key:       "username",
						},
					},
				},
			},
			wantErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			scheme := runtime.NewScheme()
			_ = proxmoxv1alpha1.AddToScheme(scheme)

			fakeClient := fake.NewClientBuilder().
				WithScheme(scheme).
				Build()

			r := &ProxmoxVMReconciler{
				Client: fakeClient,
				Scheme: scheme,
			}

			ctx := context.Background()
			_, err := r.getCredentials(ctx, tt.providerConfig)
			if (err != nil) != tt.wantErr {
				t.Errorf("getCredentials() error = %v, wantErr %v", err, tt.wantErr)
			}
		})
	}
}

