package opsservice

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/pkg/common/message"
)

func TestVMClusterService_CreateVMCluster(t *testing.T) {
	service := GetVMClusterService()

	req := message.CreateVMClusterReq{
		Name: "test-cluster",
		Values: map[string]interface{}{
			"ha-mode": true,
			"vmselect": map[string]interface{}{
				"service": map[string]interface{}{
					"type": "LoadBalancer",
				},
			},
		},
	}

	resp, err := service.CreateVMCluster(context.Background(), req)

	assert.NoError(t, err)
	assert.Equal(t, "vmclusters/test-cluster", resp.Name)
	assert.Equal(t, message.VMClusterStatusDeploying, resp.Status)
	assert.NotEmpty(t, resp.ID)
	assert.Equal(t, req.Values, resp.Values)
	assert.Equal(t, "test-cluster", resp.HelmReleaseInfo.ReleaseName)
	assert.Equal(t, "observability", resp.HelmReleaseInfo.ReleaseNamespace)
}

func TestVMClusterService_GetVMCluster(t *testing.T) {
	service := GetVMClusterService()

	req := message.GetVMClusterReq{
		ID: "test-cluster-id",
	}

	resp, err := service.GetVMCluster(context.Background(), req)

	assert.NoError(t, err)
	assert.Equal(t, "vmclusters/cluster-test-cluster-id", resp.Name)
	assert.Equal(t, "test-cluster-id", resp.ID)
	assert.Equal(t, message.VMClusterStatusRunning, resp.Status)
	assert.NotEmpty(t, resp.Endpoints)
	assert.Contains(t, resp.Endpoints, "prometheus")
	assert.Contains(t, resp.Endpoints, "grafana")
}

func TestVMClusterService_ListVMClusters(t *testing.T) {
	service := GetVMClusterService()

	req := message.ListVMClustersReq{}

	resp, err := service.ListVMClusters(context.Background(), req)

	assert.NoError(t, err)
	assert.Len(t, resp.VMClusters, 2) // Mock returns 2 clusters

	// Verify first cluster
	cluster1 := resp.VMClusters[0]
	assert.Equal(t, "vmclusters/my-cluster-1", cluster1.Name)
	assert.Equal(t, "cluster-1-id", cluster1.ID)
	assert.Equal(t, message.VMClusterStatusRunning, cluster1.Status)

	// Verify second cluster
	cluster2 := resp.VMClusters[1]
	assert.Equal(t, "vmclusters/another-vm", cluster2.Name)
	assert.Equal(t, "cluster-2-id", cluster2.ID)
	assert.Equal(t, message.VMClusterStatusUpdating, cluster2.Status)
}

func TestVMClusterService_UpdateVMCluster(t *testing.T) {
	service := GetVMClusterService()

	req := message.UpdateVMClusterReq{
		ID: "test-cluster-id",
		Values: map[string]interface{}{
			"vmstorage": map[string]interface{}{
				"resources": map[string]interface{}{
					"limits": map[string]interface{}{
						"cpu":    "1000m",
						"memory": "4Gi",
					},
				},
			},
		},
	}

	resp, err := service.UpdateVMCluster(context.Background(), req)

	assert.NoError(t, err)
	assert.Equal(t, "vmclusters/cluster-test-cluster-id", resp.Name)
	assert.Equal(t, "test-cluster-id", resp.ID)
	assert.Equal(t, message.VMClusterStatusUpdating, resp.Status)
	assert.Equal(t, req.Values, resp.Values)
}

func TestVMClusterService_DeleteVMCluster(t *testing.T) {
	service := GetVMClusterService()

	req := message.DeleteVMClusterReq{
		ID: "test-cluster-id",
	}

	resp, err := service.DeleteVMCluster(context.Background(), req)

	assert.NoError(t, err)
	assert.Contains(t, resp.Message, "test-cluster-id")
	assert.Contains(t, resp.Message, "deletion initiated")
}
