package worker

import (
	"context"
	"testing"
	"time"

	"github.com/orchard9/rdev/internal/domain"
)

func TestSDLCTaskExecutor_ParseSpec(t *testing.T) {
	exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
		Namespace: "rdev",
	})

	t.Run("valid spec", func(t *testing.T) {
		spec, err := exec.parseSpec(map[string]any{
			"command":       "feature-create",
			"args":          []any{"auth-flow", "--title", "Authentication Flow"},
			"git_clone_url": "https://git.example.com/owner/repo.git",
			"auto_commit":   true,
			"auto_push":     true,
		})
		if err != nil {
			t.Fatalf("parseSpec() error = %v", err)
		}
		if spec.Command != "feature-create" {
			t.Errorf("got command %q, want %q", spec.Command, "feature-create")
		}
		if len(spec.Args) != 3 {
			t.Errorf("got %d args, want 3", len(spec.Args))
		}
		if spec.GitCloneURL != "https://git.example.com/owner/repo.git" {
			t.Errorf("got git_clone_url %q", spec.GitCloneURL)
		}
		if !spec.AutoCommit {
			t.Error("expected auto_commit = true")
		}
		if !spec.AutoPush {
			t.Error("expected auto_push = true")
		}
	})

	t.Run("missing command", func(t *testing.T) {
		_, err := exec.parseSpec(map[string]any{
			"git_clone_url": "https://git.example.com/owner/repo.git",
		})
		if err == nil {
			t.Error("expected error for missing command")
		}
	})

	t.Run("missing git_clone_url", func(t *testing.T) {
		_, err := exec.parseSpec(map[string]any{
			"command": "feature-create",
		})
		if err == nil {
			t.Error("expected error for missing git_clone_url")
		}
	})

	t.Run("args as string slice", func(t *testing.T) {
		spec, err := exec.parseSpec(map[string]any{
			"command":       "feature-create",
			"args":          []string{"arg1", "arg2"},
			"git_clone_url": "https://git.example.com/owner/repo.git",
		})
		if err != nil {
			t.Fatalf("parseSpec() error = %v", err)
		}
		if len(spec.Args) != 2 {
			t.Errorf("got %d args, want 2", len(spec.Args))
		}
	})

	t.Run("empty args", func(t *testing.T) {
		spec, err := exec.parseSpec(map[string]any{
			"command":       "state",
			"git_clone_url": "https://git.example.com/owner/repo.git",
		})
		if err != nil {
			t.Fatalf("parseSpec() error = %v", err)
		}
		if len(spec.Args) != 0 {
			t.Errorf("got %d args, want 0", len(spec.Args))
		}
	})
}

func TestSDLCTaskExecutor_Execute_NoPodGitOps(t *testing.T) {
	exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
		Namespace: "rdev",
		PodGitOps: nil, // No git operations configured
	})

	task := &domain.WorkTask{
		ID:        "task-1",
		ProjectID: "project-1",
		Type:      domain.WorkTaskTypeSDLC,
		Spec: map[string]any{
			"command":       "feature-create",
			"args":          []any{"auth-flow"},
			"git_clone_url": "https://git.example.com/owner/repo.git",
		},
		CreatedAt: time.Now(),
	}

	result := exec.Execute(context.Background(), task)
	if result.Success {
		t.Error("expected failure when pod git operations not configured")
	}
	if result.Error == "" {
		t.Error("expected error message")
	}
}

func TestSDLCTaskExecutor_Execute_InvalidSpec(t *testing.T) {
	exec := NewSDLCTaskExecutor(SDLCTaskExecutorConfig{
		Namespace: "rdev",
	})

	task := &domain.WorkTask{
		ID:        "task-1",
		ProjectID: "project-1",
		Type:      domain.WorkTaskTypeSDLC,
		Spec:      map[string]any{
			// Missing required fields
		},
		CreatedAt: time.Now(),
	}

	result := exec.Execute(context.Background(), task)
	if result.Success {
		t.Error("expected failure for invalid spec")
	}
	if result.Error == "" {
		t.Error("expected error message for invalid spec")
	}
}

func TestSDLCTaskSpec_Valid(t *testing.T) {
	// Verify the domain type is valid
	spec := domain.SDLCTaskSpec{
		Command:     "feature-create",
		Args:        []string{"auth-flow", "--title", "Auth Flow"},
		GitCloneURL: "https://git.example.com/owner/repo.git",
		AutoCommit:  true,
		AutoPush:    true,
	}

	if spec.Command == "" {
		t.Error("command should not be empty")
	}
	if len(spec.Args) != 3 {
		t.Errorf("got %d args, want 3", len(spec.Args))
	}
}

func TestShellQuote(t *testing.T) {
	tests := []struct {
		name  string
		input string
		want  string
	}{
		{"simple", "auth-flow", "auth-flow"},
		{"with space", "Authentication System", "'Authentication System'"},
		{"with single quote", "it's working", "'it'\"'\"'s working'"},
		{"flag", "--title", "--title"},
		{"empty", "", ""},
		{"with dollar", "$HOME", "'$HOME'"},
		{"with backtick", "`cmd`", "'`cmd`'"},
		{"with semicolon", "a;b", "'a;b'"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := shellQuote(tt.input)
			if got != tt.want {
				t.Errorf("shellQuote(%q) = %q, want %q", tt.input, got, tt.want)
			}
		})
	}
}
