package store

import (
	"context"
	"testing"
	"time"
)

func TestListJobsByHost_OrderingAndLimit(t *testing.T) {
	t.Parallel()
	s := openTestStore(t)
	ctx := context.Background()

	const hostID = "h-jobs-1"
	seedHost(t, s, hostID)

	// Create three jobs with explicit CreatedAt offsets.
	base := time.Now().UTC().Truncate(time.Second)
	for i, d := range []time.Duration{-3 * time.Hour, -1 * time.Hour, -2 * time.Hour} {
		j := Job{
			ID:        "j-" + string(rune('a'+i)) + "0000000000000000000000000",
			HostID:    hostID,
			Kind:      "backup",
			ActorKind: "user",
			CreatedAt: base.Add(d),
		}
		// Truncate ID to 26 chars (ULID width); the test only needs it
		// to be unique and stable across rows.
		j.ID = j.ID[:26]
		if err := s.CreateJob(ctx, j); err != nil {
			t.Fatalf("create job %d: %v", i, err)
		}
	}

	jobs, err := s.ListJobsByHost(ctx, hostID, 100)
	if err != nil {
		t.Fatalf("list: %v", err)
	}
	if len(jobs) != 3 {
		t.Fatalf("want 3 jobs, got %d", len(jobs))
	}
	// Newest first ordering by created_at DESC.
	for i := 0; i < len(jobs)-1; i++ {
		if !jobs[i].CreatedAt.After(jobs[i+1].CreatedAt) && !jobs[i].CreatedAt.Equal(jobs[i+1].CreatedAt) {
			t.Fatalf("ordering broken at %d: %v then %v", i, jobs[i].CreatedAt, jobs[i+1].CreatedAt)
		}
	}

	// Limit clamps results.
	limited, err := s.ListJobsByHost(ctx, hostID, 2)
	if err != nil {
		t.Fatalf("list limit: %v", err)
	}
	if len(limited) != 2 {
		t.Fatalf("limit 2: want 2 jobs, got %d", len(limited))
	}
}

func TestListJobsByHost_OnlyThisHost(t *testing.T) {
	t.Parallel()
	s := openTestStore(t)
	ctx := context.Background()

	const a, b = "h-jobs-a", "h-jobs-b"
	seedHost(t, s, a)
	seedHost(t, s, b)

	now := time.Now().UTC()
	if err := s.CreateJob(ctx, Job{ID: "01HZZZZZZZZZZZZZZZZZZZZZ01", HostID: a, Kind: "backup", ActorKind: "user", CreatedAt: now}); err != nil {
		t.Fatalf("create a: %v", err)
	}
	if err := s.CreateJob(ctx, Job{ID: "01HZZZZZZZZZZZZZZZZZZZZZ02", HostID: b, Kind: "backup", ActorKind: "user", CreatedAt: now}); err != nil {
		t.Fatalf("create b: %v", err)
	}

	jobs, err := s.ListJobsByHost(ctx, a, 100)
	if err != nil {
		t.Fatalf("list a: %v", err)
	}
	if len(jobs) != 1 || jobs[0].HostID != a {
		t.Fatalf("expected 1 job for host a, got %d (%v)", len(jobs), jobs)
	}
}
