package store

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

// TestLastSentOnEmptyTableIsZero pins the aggregate-over-nothing trap that
// nudges.go's OldestPendingTelegram already documents: MAX over an empty set is
// one row holding NULL, not zero rows. Scanning that into a bare int64 is an
// error, and the doc on LastSent promises a zero time instead.
//
// It is not a cosmetic promise. ack_sends is written only by MarkSent, and
// MarkSent is called only after a repeat has already gone out, so the first
// repeat for every rule reads an empty table. delivery.Dispatcher.RepeatUnacked
// aborts the whole sweep on that error, which means the repeat-til-ack loop can
// never take its first step for any rule.
func TestLastSentOnEmptyTableIsZero(t *testing.T) {
	s := newTestStore(t)
	ctx := context.Background()

	last, err := s.LastSent(ctx, "service_down")
	if err != nil {
		t.Fatalf("last sent on an empty table must not error: %v", err)
	}
	if !last.IsZero() {
		t.Fatalf("want the zero time before anything was sent, got %v", last)
	}
}

// TestLastSentIsScopedToItsRule — a send for another rule must not answer for
// this one, or the repeat interval is clocked off somebody else's alarm.
func TestLastSentIsScopedToItsRule(t *testing.T) {
	s := newTestStore(t)
	ctx := context.Background()
	at := time.UnixMilli(1_700_000_000_000).UTC()

	if err := s.MarkSent(ctx, "other_rule", at); err != nil {
		t.Fatalf("mark sent: %v", err)
	}
	last, err := s.LastSent(ctx, "service_down")
	if err != nil {
		t.Fatalf("last sent: %v", err)
	}
	if !last.IsZero() {
		t.Fatalf("want zero for a rule with no sends, got %v", last)
	}

	if err := s.MarkSent(ctx, "service_down", at); err != nil {
		t.Fatalf("mark sent: %v", err)
	}
	last, err = s.LastSent(ctx, "service_down")
	if err != nil {
		t.Fatalf("last sent: %v", err)
	}
	if !last.Equal(at) {
		t.Fatalf("want %v, got %v", at, last)
	}
}
