package core

import (
	"testing"
)

func TestDagValidate(t *testing.T) {
	t.Run("DAG valido retorna Valid true y levels calculados", func(t *testing.T) {
		dag := DagDefinition{
			Name: "valid-dag",
			Steps: []DagStep{
				{Name: "a", Command: "echo a"},
				{Name: "b", Command: "echo b", Depends: []string{"a"}},
				{Name: "c", Command: "echo c", Depends: []string{"a"}},
				{Name: "d", Command: "echo d", Depends: []string{"b", "c"}},
			},
		}
		res := DagValidate(dag)
		if !res.Valid {
			t.Errorf("Valid: got false, want true. Errors: %v", res.Errors)
		}
		if len(res.Errors) != 0 {
			t.Errorf("Errors: got %v, want empty", res.Errors)
		}
		// Should have 3 levels: [a], [b,c], [d]
		if len(res.Levels) != 3 {
			t.Errorf("Levels: got %d, want 3. Levels: %v", len(res.Levels), res.Levels)
		}
		if len(res.Levels[0]) != 1 || res.Levels[0][0] != "a" {
			t.Errorf("Levels[0]: got %v, want [a]", res.Levels[0])
		}
		if len(res.Levels[2]) != 1 || res.Levels[2][0] != "d" {
			t.Errorf("Levels[2]: got %v, want [d]", res.Levels[2])
		}
	})

	t.Run("step sin nombre retorna error", func(t *testing.T) {
		dag := DagDefinition{
			Name: "bad-dag",
			Steps: []DagStep{
				{Command: "echo hello"}, // no name, no ID
			},
		}
		res := DagValidate(dag)
		if res.Valid {
			t.Error("Valid: got true, want false")
		}
		if len(res.Errors) == 0 {
			t.Error("Errors: got empty, want at least one error")
		}
	})

	t.Run("depends a step inexistente retorna error", func(t *testing.T) {
		dag := DagDefinition{
			Name: "bad-deps-dag",
			Steps: []DagStep{
				{Name: "step1", Command: "echo ok"},
				{Name: "step2", Command: "echo ok", Depends: []string{"nonexistent"}},
			},
		}
		res := DagValidate(dag)
		if res.Valid {
			t.Error("Valid: got true, want false")
		}
		found := false
		for _, e := range res.Errors {
			if containsStr(e, "nonexistent") {
				found = true
				break
			}
		}
		if !found {
			t.Errorf("Errors should mention 'nonexistent', got: %v", res.Errors)
		}
	})

	t.Run("ciclo en dependencias retorna error", func(t *testing.T) {
		dag := DagDefinition{
			Name: "cyclic-dag",
			Steps: []DagStep{
				{Name: "a", Command: "echo a", Depends: []string{"b"}},
				{Name: "b", Command: "echo b", Depends: []string{"a"}},
			},
		}
		res := DagValidate(dag)
		if res.Valid {
			t.Error("Valid: got true, want false")
		}
		found := false
		for _, e := range res.Errors {
			if containsStr(e, "cycle") {
				found = true
				break
			}
		}
		if !found {
			t.Errorf("Errors should mention 'cycle', got: %v", res.Errors)
		}
	})
}

// containsStr returns true if s contains substr.
func containsStr(s, substr string) bool {
	return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
		func() bool {
			for i := 0; i <= len(s)-len(substr); i++ {
				if s[i:i+len(substr)] == substr {
					return true
				}
			}
			return false
		}())
}
