package cli

import (
	"testing"

	"git.cloudinit.dev/coreci/orca/internal/jobspec"
)

func TestSplitCommand(t *testing.T) {
	tests := []struct {
		name     string
		input    string
		wantBin  string
		wantArgs []string
	}{
		{
			name:     "single binary",
			input:    "/bin/true",
			wantBin:  "/bin/true",
			wantArgs: nil,
		},
		{
			name:     "binary with one arg",
			input:    "/bin/echo hello",
			wantBin:  "/bin/echo",
			wantArgs: []string{"hello"},
		},
		{
			name:     "binary with multiple args",
			input:    "/usr/bin/httpd -f /etc/orca/web-app/httpd.conf",
			wantBin:  "/usr/bin/httpd",
			wantArgs: []string{"-f", "/etc/orca/web-app/httpd.conf"},
		},
		{
			name:     "binary with sh -c and quoted string",
			input:    "/bin/sh -c 'echo hello world'",
			wantBin:  "/bin/sh",
			wantArgs: []string{"-c", "'echo", "hello", "world'"},
		},
		{
			name:     "empty command falls back to /bin/true",
			input:    "",
			wantBin:  "/bin/true",
			wantArgs: nil,
		},
		{
			name:     "all-whitespace command falls back to /bin/true",
			input:    "   \t  ",
			wantBin:  "/bin/true",
			wantArgs: nil,
		},
		{
			name:     "multiple spaces between args",
			input:    "/bin/echo    hello     world",
			wantBin:  "/bin/echo",
			wantArgs: []string{"hello", "world"},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			gotBin, gotArgs := splitCommand(tt.input)
			if gotBin != tt.wantBin {
				t.Errorf("splitCommand(%q) bin = %q, want %q", tt.input, gotBin, tt.wantBin)
			}
			if len(gotArgs) != len(tt.wantArgs) {
				t.Errorf("splitCommand(%q) args len = %d, want %d (got %v, want %v)",
					tt.input, len(gotArgs), len(tt.wantArgs), gotArgs, tt.wantArgs)
				return
			}
			for i, a := range gotArgs {
				if a != tt.wantArgs[i] {
					t.Errorf("splitCommand(%q) args[%d] = %q, want %q",
						tt.input, i, a, tt.wantArgs[i])
				}
			}
		})
	}
}

func TestWorkloadToTaskSpecs_SplitsCommand(t *testing.T) {
	spec := &jobspec.WorkloadSpec{
		Name: "web-app",
		Runtime: &jobspec.RuntimeBlock{
			OneOf:   "process",
			Command: "/usr/bin/httpd -f /etc/orca/web-app/httpd.conf",
		},
	}
	tasks := workloadToTaskSpecs(spec)
	if len(tasks) != 1 {
		t.Fatalf("expected 1 task, got %d", len(tasks))
	}
	if tasks[0].Command != "/usr/bin/httpd" {
		t.Errorf("expected Command=/usr/bin/httpd, got %q", tasks[0].Command)
	}
	if len(tasks[0].Args) != 2 {
		t.Fatalf("expected 2 args, got %d (%v)", len(tasks[0].Args), tasks[0].Args)
	}
	if tasks[0].Args[0] != "-f" || tasks[0].Args[1] != "/etc/orca/web-app/httpd.conf" {
		t.Errorf("expected args [-f /etc/orca/web-app/httpd.conf], got %v", tasks[0].Args)
	}
}

func TestWorkloadToTaskSpecs_NilRuntimeUsesBinTrue(t *testing.T) {
	spec := &jobspec.WorkloadSpec{
		Name: "noop",
	}
	tasks := workloadToTaskSpecs(spec)
	if len(tasks) != 1 {
		t.Fatalf("expected 1 task, got %d", len(tasks))
	}
	if tasks[0].Command != "/bin/true" {
		t.Errorf("expected Command=/bin/true, got %q", tasks[0].Command)
	}
	if len(tasks[0].Args) != 0 {
		t.Errorf("expected 0 args, got %d (%v)", len(tasks[0].Args), tasks[0].Args)
	}
}

func TestWorkloadToTaskSpecs_EmptyCommandUsesBinTrue(t *testing.T) {
	spec := &jobspec.WorkloadSpec{
		Name: "empty",
		Runtime: &jobspec.RuntimeBlock{
			OneOf:   "process",
			Command: "",
		},
	}
	tasks := workloadToTaskSpecs(spec)
	if len(tasks) != 1 {
		t.Fatalf("expected 1 task, got %d", len(tasks))
	}
	if tasks[0].Command != "/bin/true" {
		t.Errorf("expected Command=/bin/true, got %q", tasks[0].Command)
	}
}

func TestWorkloadToTaskSpecs_NilSpecReturnsNil(t *testing.T) {
	tasks := workloadToTaskSpecs(nil)
	if tasks != nil {
		t.Errorf("expected nil, got %v", tasks)
	}
}
