package jobspec

import (
	"testing"
)

func TestREQ152_ScheduleTimeoutDaemonSet(t *testing.T) {
	input := "---\n" +
		"kind: DaemonSet\n" +
		"name: logs\n" +
		"schedule:\n" +
		"  mode: every-node\n" +
		"  cron: \"*/5 * * * *\"\n" +
		"timeout: 30s\n" +
		"restart:\n" +
		"  mode: service\n" +
		"runtime:\n" +
		"  one_of: process\n" +
		"  command: /bin/true\n" +
		"---\nbody\n"
	spec, err := ParseMarkdown([]byte(input))
	if err != nil {
		t.Fatalf("ParseMarkdown: %v", err)
	}
	if spec.Count != 0 {
		t.Errorf("DaemonSet Count = %d, want 0 (no default)", spec.Count)
	}
	if spec.Schedule == nil {
		t.Fatal("Schedule is nil")
	}
	if spec.Schedule.Mode != "every-node" {
		t.Errorf("Schedule.Mode = %q, want every-node", spec.Schedule.Mode)
	}
	if spec.Schedule.Cron != "*/5 * * * *" {
		t.Errorf("Schedule.Cron = %q, want */5 * * * *", spec.Schedule.Cron)
	}
	if spec.Timeout != "30s" {
		t.Errorf("Timeout = %q, want 30s", spec.Timeout)
	}
}

func TestREQ152_JobScheduleTimeout(t *testing.T) {
	input := "---\n" +
		"kind: Job\n" +
		"name: nightly\n" +
		"schedule:\n" +
		"  cron: \"0 2 * * *\"\n" +
		"timeout: 1h\n" +
		"runtime:\n" +
		"  one_of: process\n" +
		"  command: /bin/true\n" +
		"---\nbody\n"
	spec, err := ParseMarkdown([]byte(input))
	if err != nil {
		t.Fatalf("ParseMarkdown: %v", err)
	}
	if spec.Count != 1 {
		t.Errorf("Job Count = %d, want 1 (default)", spec.Count)
	}
	if spec.Schedule == nil || spec.Schedule.Cron != "0 2 * * *" {
		t.Errorf("Schedule.Cron = %+v, want 0 2 * * *", spec.Schedule)
	}
	if spec.Timeout != "1h" {
		t.Errorf("Timeout = %q, want 1h", spec.Timeout)
	}
}

// TestREQ152_DaemonSetPassesLint verifies a DaemonSet spec with a
// schedule block, restart, and runtime parses AND validates cleanly
// under the schema (T11). DaemonSet must NOT default Count to 1.
func TestREQ152_DaemonSetPassesLint(t *testing.T) {
	input := "---\n" +
		"kind: DaemonSet\n" +
		"name: log-shipper\n" +
		"schedule:\n" +
		"  mode: every-node\n" +
		"restart:\n" +
		"  mode: service\n" +
		"  max_retries: 5\n" +
		"  delay: 5s\n" +
		"runtime:\n" +
		"  one_of: process\n" +
		"  command: /usr/local/bin/log-shipper\n" +
		"---\n# Log shipper\n\nRuns on every node.\n"
	spec, err := ParseMarkdown([]byte(input))
	if err != nil {
		t.Fatalf("ParseMarkdown: %v", err)
	}
	if spec.Count != 0 {
		t.Errorf("DaemonSet Count = %d, want 0", spec.Count)
	}
	if spec.Schedule == nil || spec.Schedule.Mode != "every-node" {
		t.Errorf("Schedule.Mode = %+v, want every-node", spec.Schedule)
	}
	if spec.Restart == nil || spec.Restart.Mode != "service" {
		t.Errorf("Restart.Mode = %+v, want service", spec.Restart)
	}
}

// TestREQ152_TimeoutEnforced verifies the timeout field is parsed and
// stored on the WorkloadSpec (T12).
func TestREQ152_TimeoutEnforced(t *testing.T) {
	cases := []struct {
		timeout string
		want    string
	}{
		{"30s", "30s"},
		{"5m", "5m"},
		{"1h30m", "1h30m"},
		{"900s", "900s"},
	}
	for _, c := range cases {
		input := "---\nkind: Job\nname: t\ntimeout: " + c.timeout + "\nruntime:\n  one_of: process\n  command: /bin/true\n---\nbody\n"
		spec, err := ParseMarkdown([]byte(input))
		if err != nil {
			t.Fatalf("ParseMarkdown(%q): %v", c.timeout, err)
		}
		if spec.Timeout != c.want {
			t.Errorf("Timeout = %q, want %q", spec.Timeout, c.want)
		}
	}
}

// TestREQ152_DaemonSetExplicitCountRejected verifies that an explicit
// count on a DaemonSet is preserved (parser does not override it) so
// the validator can reject it.
func TestREQ152_DaemonSetExplicitCountPreserved(t *testing.T) {
	input := "---\nkind: DaemonSet\nname: d\ncount: 3\nschedule:\n  mode: every-node\nrestart:\n  mode: service\nruntime:\n  one_of: process\n  command: /bin/true\n---\nbody\n"
	spec, err := ParseMarkdown([]byte(input))
	if err != nil {
		t.Fatalf("ParseMarkdown: %v", err)
	}
	if spec.Count != 3 {
		t.Errorf("DaemonSet explicit Count = %d, want 3 (preserved, not defaulted)", spec.Count)
	}
}
