package config

import (
	"testing"

	"github.com/jfraeys/fetch_ml/internal/config"
)

func TestDefaultConstants(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test default values
	tests := []struct {
		name     string
		actual   any
		expected any
	}{
		{"DefaultSSHPort", config.DefaultSSHPort, 22},
		{"DefaultRedisPort", config.DefaultRedisPort, 6379},
		{"DefaultRedisAddr", config.DefaultRedisAddr, "localhost:6379"},
		{"DefaultBasePath", config.DefaultBasePath, "/mnt/nas/jobs"},
		{"DefaultTrainScript", config.DefaultTrainScript, "train.py"},
		{"DefaultDataDir", config.DefaultDataDir, "/data/active"},
		{"DefaultLocalDataDir", config.DefaultLocalDataDir, "./data/active"},
		{"DefaultNASDataDir", config.DefaultNASDataDir, "/mnt/datasets"},
		{"DefaultMaxWorkers", config.DefaultMaxWorkers, 2},
		{"DefaultPollInterval", config.DefaultPollInterval, 5},
		{"DefaultMaxAgeHours", config.DefaultMaxAgeHours, 24},
		{"DefaultMaxSizeGB", config.DefaultMaxSizeGB, 100},
		{"DefaultCleanupInterval", config.DefaultCleanupInterval, 60},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.actual != tt.expected {
				t.Errorf("Expected %s to be %v, got %v", tt.name, tt.expected, tt.actual)
			}
		})
	}
}

func TestRedisKeyConstants(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test Redis key prefixes
	tests := []struct {
		name     string
		actual   string
		expected string
	}{
		{"RedisTaskQueueKey", config.RedisTaskQueueKey, "ml:queue"},
		{"RedisTaskPrefix", config.RedisTaskPrefix, "ml:task:"},
		{"RedisJobMetricsPrefix", config.RedisJobMetricsPrefix, "ml:metrics:"},
		{"RedisTaskStatusPrefix", config.RedisTaskStatusPrefix, "ml:status:"},
		{"RedisWorkerHeartbeat", config.RedisWorkerHeartbeat, "ml:workers:heartbeat"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.actual != tt.expected {
				t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
			}
		})
	}
}

func TestTaskStatusConstants(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test task status constants
	tests := []struct {
		name     string
		actual   string
		expected string
	}{
		{"TaskStatusQueued", config.TaskStatusQueued, "queued"},
		{"TaskStatusRunning", config.TaskStatusRunning, "running"},
		{"TaskStatusCompleted", config.TaskStatusCompleted, "completed"},
		{"TaskStatusFailed", config.TaskStatusFailed, "failed"},
		{"TaskStatusCancelled", config.TaskStatusCancelled, "cancelled"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.actual != tt.expected {
				t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
			}
		})
	}
}

func TestJobStatusConstants(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test job status constants
	tests := []struct {
		name     string
		actual   string
		expected string
	}{
		{"JobStatusPending", config.JobStatusPending, "pending"},
		{"JobStatusQueued", config.JobStatusQueued, "queued"},
		{"JobStatusRunning", config.JobStatusRunning, "running"},
		{"JobStatusFinished", config.JobStatusFinished, "finished"},
		{"JobStatusFailed", config.JobStatusFailed, "failed"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.actual != tt.expected {
				t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
			}
		})
	}
}

func TestPodmanConstants(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test Podman defaults
	tests := []struct {
		name     string
		actual   string
		expected string
	}{
		{"DefaultPodmanMemory", config.DefaultPodmanMemory, "8g"},
		{"DefaultPodmanCPUs", config.DefaultPodmanCPUs, "2"},
		{"DefaultContainerWorkspace", config.DefaultContainerWorkspace, "/workspace"},
		{"DefaultContainerResults", config.DefaultContainerResults, "/workspace/results"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.actual != tt.expected {
				t.Errorf("Expected %s to be %s, got %s", tt.name, tt.expected, tt.actual)
			}
		})
	}
}

func TestConstantsConsistency(t *testing.T) {
	t.Parallel() // Enable parallel execution

	// Test that related constants are consistent
	if config.DefaultRedisAddr != "localhost:6379" {
		t.Errorf("Expected DefaultRedisAddr to use DefaultRedisPort, got %s", config.DefaultRedisAddr)
	}

	// Test that Redis key prefixes are consistent
	if config.RedisTaskPrefix == config.RedisJobMetricsPrefix {
		t.Error("Redis task prefix and metrics prefix should be different")
	}

	// Test that status constants don't overlap
	taskStatuses := []string{
		config.TaskStatusQueued,
		config.TaskStatusRunning,
		config.TaskStatusCompleted,
		config.TaskStatusFailed,
		config.TaskStatusCancelled,
	}

	jobStatuses := []string{
		config.JobStatusPending,
		config.JobStatusQueued,
		config.JobStatusRunning,
		config.JobStatusFinished,
		config.JobStatusFailed,
	}

	// Check for duplicates within task statuses
	for i, status1 := range taskStatuses {
		for j, status2 := range taskStatuses {
			if i != j && status1 == status2 {
				t.Errorf("Duplicate task status found: %s", status1)
			}
		}
	}

	// Check for duplicates within job statuses
	for i, status1 := range jobStatuses {
		for j, status2 := range jobStatuses {
			if i != j && status1 == status2 {
				t.Errorf("Duplicate job status found: %s", status1)
			}
		}
	}
}
