package clusters

import (
	"testing"

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

func TestRegisterCluster(t *testing.T) {
	cm := NewClusterManager()
	
	err := cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	assert.NoError(t, err)
	
	cluster, exists := cm.GetCluster("prod")
	assert.True(t, exists)
	assert.Equal(t, "prod", cluster.Name)
}

func TestUnregisterCluster(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	err := cm.UnregisterCluster("prod")
	assert.NoError(t, err)
	
	_, exists := cm.GetCluster("prod")
	assert.False(t, exists)
}

func TestListClusters(t *testing.T) {
	cm := NewClusterManager()
	
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	cm.RegisterCluster("staging", "https://k8s-staging.com", 50)
	
	clusters := cm.ListClusters()
	assert.Equal(t, 2, len(clusters))
}

func TestHealthCheck(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	err := cm.HealthCheck("prod")
	assert.NoError(t, err)
	
	cluster, _ := cm.GetCluster("prod")
	assert.True(t, cluster.Healthy)
}

func TestMarkUnhealthy(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	cm.MarkUnhealthy("prod")
	
	cluster, _ := cm.GetCluster("prod")
	assert.False(t, cluster.Healthy)
}

func TestAllocateTask(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	err := cm.AllocateTask("prod")
	assert.NoError(t, err)
	
	cluster, _ := cm.GetCluster("prod")
	assert.Equal(t, 1, cluster.Usage)
}

func TestAllocateTaskUnhealthy(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	cm.MarkUnhealthy("prod")
	
	err := cm.AllocateTask("prod")
	assert.Error(t, err)
}

func TestAllocateTaskAtCapacity(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 1)
	
	cm.AllocateTask("prod")
	err := cm.AllocateTask("prod")
	
	assert.Error(t, err)
}

func TestReleaseTask(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	cm.AllocateTask("prod")
	cm.ReleaseTask("prod")
	
	cluster, _ := cm.GetCluster("prod")
	assert.Equal(t, 0, cluster.Usage)
}

func TestFindBestCluster(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	cm.RegisterCluster("staging", "https://k8s-staging.com", 50)
	
	cm.AllocateTask("staging")
	cm.AllocateTask("staging")
	
	best, err := cm.FindBestCluster()
	assert.NoError(t, err)
	assert.Equal(t, "prod", best)
}

func TestGetCapacitySummary(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	cm.RegisterCluster("staging", "https://k8s-staging.com", 50)
	
	cm.AllocateTask("prod")
	
	summary := cm.GetCapacitySummary()
	assert.Equal(t, 150, summary["total_capacity"])
	assert.Equal(t, 1, summary["total_usage"])
	assert.Equal(t, 2, summary["healthy_clusters"])
}

func TestGetHealthStatus(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	cm.RegisterCluster("staging", "https://k8s-staging.com", 50)
	
	cm.MarkUnhealthy("staging")
	
	status := cm.GetHealthStatus()
	assert.True(t, status["prod"])
	assert.False(t, status["staging"])
}

func TestRegisterClusterError(t *testing.T) {
	cm := NewClusterManager()
	cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	
	err := cm.RegisterCluster("prod", "https://k8s-prod.com", 100)
	assert.Error(t, err)
}
