package queryv1

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

func TestAggregateOverflowSentinelDoesNotEnlargeOrdinaryPages(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	request := Request{ObjectID: "Issue", GroupBy: "Status", AggregateFetchLimit: 2001,
		Selections: []Selection{{Kind: SelectionField, Field: "Status"}},
	}
	if err := ValidateRequest(ctx, request); err != nil {
		t.Fatalf("the aggregate overflow probe must reach execution: %v", err)
	}
	request.AggregateFetchLimit = 2002
	assertProbeRowFailure(t, ValidateRequest(ctx, request), 2001)
	request.AggregateFetchLimit = 2001
	request.Limit = 2001
	assertProbeRowFailure(t, ValidateRequest(ctx, request), 2000)

	response := Response{Done: true, Aggregate: true,
		Receipts: Receipts{ProtocolVersion: "1.0", CapabilityVersion: CapabilityName},
		Records:  make([]Record, 2001),
	}
	if err := ValidateResponse(response); err != nil {
		t.Fatalf("overflow sentinel must reach the caller: %v", err)
	}
	response.Records = append(response.Records, Record{})
	assertProbeRowFailure(t, ValidateResponse(response), 2001)
	response.Records = response.Records[:2001]
	response.Aggregate = false
	assertProbeRowFailure(t, ValidateResponse(response), 2000)
}

func assertProbeRowFailure(t *testing.T, err error, maximum uint64) {
	t.Helper()
	var failure *Failure
	if !errors.As(err, &failure) || failure.Category != FailureResourceExhausted ||
		failure.LimitKind != LimitRecordCount || failure.Maximum != maximum {
		t.Fatalf("row bound must remain %d: %#v, %v", maximum, failure, err)
	}
}
