package report

import (
	"strings"
	"testing"

	"gitea.dooplex.hu/admin/felhom-controller/internal/metrics"
)

func appWithIssue(name string, count, ctxBytes int) AppTelemetry {
	var ctx []string
	if ctxBytes > 0 {
		ctx = []string{strings.Repeat("c", ctxBytes)}
	}
	return AppTelemetry{
		AppName: name,
		Issues:  []metrics.LogIssue{{Severity: "error", Message: name + " boom", Count: count, Context: ctx}},
	}
}

// Part B caps — budget overflow drops context from the LOWEST-count issues first,
// across apps. Red-proof: inverting the sort (highest first) keeps the wrong survivor.
func TestEnforceContextBudget_DropsLowestCountFirst(t *testing.T) {
	apps := []AppTelemetry{
		appWithIssue("rare", 2, 600),      // lowest count — first to lose context
		appWithIssue("frequent", 50, 600), // must keep context
		appWithIssue("medium", 10, 600),   // dropped second
	}
	enforceContextBudget(apps, 1000) // total 1800 → must shed 800 → drop rare, then medium

	if apps[0].Issues[0].Context != nil {
		t.Fatalf("lowest-count issue kept its context")
	}
	if apps[2].Issues[0].Context != nil {
		t.Fatalf("second-lowest issue kept its context (still over budget after one drop)")
	}
	if len(apps[1].Issues[0].Context) == 0 {
		t.Fatalf("highest-count issue LOST its context — wrong drop order")
	}
}

func TestEnforceContextBudget_UnderBudgetUntouched(t *testing.T) {
	apps := []AppTelemetry{appWithIssue("a", 1, 100), appWithIssue("b", 2, 100)}
	enforceContextBudget(apps, 16*1024)
	if len(apps[0].Issues[0].Context) == 0 || len(apps[1].Issues[0].Context) == 0 {
		t.Fatalf("under-budget contexts must be untouched")
	}
}
