package connector_events

import (
	"context"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
)

func TestClaimPressureFiltersQueueClass(t *testing.T) {
	svc, mock := newMock(t)

	// The claimable CASE arms now embed the NextAttemptAt-gated ordering guard
	// (NCRM #3139) six times; each embed adds two `now` binds, so the leading
	// time-binds grow to 18 after pending not-before gates are included.
	mock.ExpectQuery(`COALESCE\(e\.QueueClass, 'default'\) IN \(\?\)`).
		WithArgs(
			sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(),
			sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(),
			sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(),
			sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg(),
			sqlmock.AnyArg(), sqlmock.AnyArg(),
			"pack-1", "interactive").
		WillReturnRows(sqlmock.NewRows([]string{
			"pending_count",
			"failed_due_count",
			"stale_processing_count",
			"processing_count",
			"oldest_claimable_at",
		}).AddRow(2, 1, 0, 3, time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)))

	snapshot, err := svc.ClaimPressure(context.Background(), "pack-1", []string{" interactive "})
	if err != nil {
		t.Fatalf("ClaimPressure: %v", err)
	}
	if snapshot.ClaimableCount != 3 {
		t.Fatalf("ClaimableCount = %d, want 3", snapshot.ClaimableCount)
	}
	if len(snapshot.QueueClasses) != 1 || snapshot.QueueClasses[0] != " interactive " {
		t.Fatalf("QueueClasses snapshot = %v", snapshot.QueueClasses)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("unmet expectations: %v", err)
	}
}

func TestProcessingPressureFiltersQueueClassWithoutClaimOrderingGuard(t *testing.T) {
	svc, mock := newMock(t)

	// This probe runs before each claim-budget decision, so it must stay a cheap
	// status/date count. Claim-ordering NOT EXISTS guards are reserved for the
	// actual ClaimNext/ReclaimStaleNext paths where a row is selected.
	mock.ExpectQuery(`(?s)COUNT\(\*\).*LastModifiedDate < \?.*Status = 'processing'.*COALESCE\(e\.QueueClass, 'default'\) IN \(\?\)`).
		WithArgs(sqlmock.AnyArg(), "pack-1", "interactive").
		WillReturnRows(sqlmock.NewRows([]string{
			"processing_count",
			"stale_processing_count",
		}).AddRow(5, 2))

	snapshot, err := svc.ProcessingPressure(context.Background(), "pack-1", []string{" interactive "})
	if err != nil {
		t.Fatalf("ProcessingPressure: %v", err)
	}
	if snapshot.ProcessingCount != 5 {
		t.Fatalf("ProcessingCount = %d, want 5", snapshot.ProcessingCount)
	}
	if snapshot.StaleProcessingCount != 2 {
		t.Fatalf("StaleProcessingCount = %d, want 2", snapshot.StaleProcessingCount)
	}
	if len(snapshot.QueueClasses) != 1 || snapshot.QueueClasses[0] != " interactive " {
		t.Fatalf("QueueClasses snapshot = %v", snapshot.QueueClasses)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Errorf("unmet expectations: %v", err)
	}
}
