package diagnostics

import (
	"fmt"
	"reflect"
	"strings"
	"testing"
	"unicode/utf8"

	"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)

func TestAggregateEnforcesByteBudgetAndReportsOmissions(t *testing.T) {
	issues := make([]string, MaxIssues)
	for index := range issues {
		issues[index] = fmt.Sprintf("issue-%d-%s", index, strings.Repeat("火", MaxDisplayedRunes))
	}

	message := Aggregate("invalid D&D data", issues)
	if !utf8.ValidString(message) || len([]byte(message)) > MaxMessageBytes {
		t.Fatalf("Aggregate() returned invalid or oversized message: bytes=%d message=%q", len([]byte(message)), message)
	}
	displayed := strings.Count(message, "issue-")
	if displayed == 0 || displayed >= len(issues) {
		t.Fatalf("Aggregate() displayed %d issues, want byte-budget omission", displayed)
	}
	wantOmitted := fmt.Sprintf("%d additional issue(s) omitted", len(issues)-displayed)
	if !strings.Contains(message, wantOmitted) {
		t.Fatalf("Aggregate() = %q, want %q", message, wantOmitted)
	}
}

func TestLimitWarningsBoundsOutputAndReportsOmissions(t *testing.T) {
	warnings := make([]contracts.Warning, MaxWarnings+3)
	for index := range warnings {
		warnings[index] = contracts.Warning{ReasonCode: fmt.Sprintf("warning-%d", index)}
	}
	before := append([]contracts.Warning(nil), warnings...)

	got := LimitWarnings(warnings, "records", "warnings_omitted")
	if len(got) != MaxWarnings {
		t.Fatalf("LimitWarnings() count = %d, want %d", len(got), MaxWarnings)
	}
	summary := got[len(got)-1]
	wantOmitted := len(warnings) - (MaxWarnings - 1)
	if summary.Scope != "records" || summary.ReasonCode != "warnings_omitted" ||
		summary.Message != fmt.Sprintf("%d additional warning(s) omitted", wantOmitted) {
		t.Fatalf("summary = %#v", summary)
	}
	if !reflect.DeepEqual(warnings, before) {
		t.Fatal("LimitWarnings() mutated its input")
	}
}
