package report

import (
	"strings"
	"testing"
	"time"
)

// TestRecorderTotalsAndSummary checks call/error tallying and that the rendered
// summary surfaces operations, codes, events and stream errors.
func TestRecorderTotalsAndSummary(t *testing.T) {
	r := New()
	r.Record("game.state", "ok", 5*time.Millisecond)
	r.Record("game.state", "ok", 7*time.Millisecond)
	r.Record("game.submit_play", "not_your_turn", 3*time.Millisecond)
	r.Record("hammer:games.list", "rate_limited", time.Millisecond)
	r.Event("your_turn")
	r.Event("your_turn")
	r.StreamErr()

	calls, nonOK := r.Totals()
	if calls != 4 {
		t.Errorf("calls = %d, want 4", calls)
	}
	if nonOK != 2 {
		t.Errorf("nonOK = %d, want 2", nonOK)
	}

	s := r.Summary()
	for _, want := range []string{"game.state", "not_your_turn", "rate_limited", "your_turn", "stream errors: 1"} {
		if !strings.Contains(s, want) {
			t.Errorf("summary missing %q\n---\n%s", want, s)
		}
	}
}

// TestOpStatQuantile checks the bucketed percentile estimate lands on the right bucket
// bound.
func TestOpStatQuantile(t *testing.T) {
	s := newOpStat()
	for i := 0; i < 90; i++ {
		s.record("ok", 10*time.Millisecond)
	}
	for i := 0; i < 10; i++ {
		s.record("ok", 1000*time.Millisecond)
	}
	if got := s.quantile(0.50); got != "10" {
		t.Errorf("p50 = %s, want 10", got)
	}
	if got := s.quantile(0.99); got != "1000" {
		t.Errorf("p99 = %s, want 1000", got)
	}
}
