// This file verifies report determinism and plain-language replay output.
package evaluation

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"
)

func TestReplayReportIsDeterministic(t *testing.T) {
	start := time.Date(2026, 8, 1, 0, 0, 0, 0, time.UTC)
	report := &ReplayReport{
		Version:                   ReplayVersionV1Alpha1,
		ExperimentID:              "test-experiment",
		ExperimentDigest:          "experiment-digest",
		PolicyRevision:            "revision",
		PolicyType:                "CostOptimized",
		EvaluationIntervalSeconds: 300,
		Dataset: ReplayDatasetIdentity{
			ID:            "test-dataset",
			Component:     "tidb",
			Target:        O11YTargetSpec{ClusterID: "cluster-1", Vendor: "aws", Region: "us-west-2"},
			Window:        O11YQueryWindow{Start: start, End: start.Add(5 * time.Minute), StepSeconds: 60},
			ArchiveDigest: "archive-digest",
		},
		Summary: ReplaySummary{
			ScheduledPoints:                100,
			EvaluatedPoints:                99,
			SkippedPoints:                  1,
			RecommendationEpisodes:         1,
			TargetChanges:                  20,
			DirectionReversals:             10,
			HPAReferencePoints:             99,
			HPATargetChanges:               5,
			HPADirectionReversals:          2,
			ScheduledReplicaHourIntervals:  1,
			ComparableReplicaHourIntervals: 1,
			ObservedReplicaHours:           10,
			HPAReplicaHours:                8,
			RecommendedReplicaHours:        6,
		},
		Episodes: []RecommendationEpisode{{StartAt: start, EndAt: start.Add(5 * time.Minute), DecisionCount: 2, StartReason: RecommendationStartInitial, Desired: Capacity{Tier: "fixed", Replicas: 2}}},
	}

	firstDir := filepath.Join(t.TempDir(), "first")
	secondDir := filepath.Join(t.TempDir(), "second")
	firstJSON, firstMarkdown, err := WriteReplayReport(firstDir, report)
	if err != nil {
		t.Fatalf("first WriteReplayReport(): %v", err)
	}
	secondJSON, secondMarkdown, err := WriteReplayReport(secondDir, report)
	if err != nil {
		t.Fatalf("second WriteReplayReport(): %v", err)
	}

	for _, pair := range [][2]string{{firstJSON, secondJSON}, {firstMarkdown, secondMarkdown}} {
		first, readErr := os.ReadFile(pair[0])
		if readErr != nil {
			t.Fatal(readErr)
		}
		second, readErr := os.ReadFile(pair[1])
		if readErr != nil {
			t.Fatal(readErr)
		}
		if string(first) != string(second) {
			t.Fatalf("reports %s and %s differ", pair[0], pair[1])
		}
	}

	markdown, err := os.ReadFile(firstMarkdown)
	if err != nil {
		t.Fatal(err)
	}
	reportText := string(markdown)
	for _, expected := range []string{
		"## Bottom Line",
		"**Stability:** Policy changed the replica target **20 times**; HPA changed it **5 times**. Policy changed it **4.0x as often**, which means more scaling churn.",
		"Policy reversed scaling direction **10 times**; HPA reversed **2 times**.",
		"**Capacity:** Policy requested **6.000 replica-hours**, **25.0% less** than HPA's **8.000 replica-hours**.",
		"**Data quality:** The replay completed **99 of 100** scheduled evaluations (99.0%). **1** was skipped and **0** returned Policy errors.",
		"**Important limitation:** This does not prove cost savings because Policy recommendations were not executed.",
		"## What Was Replayed",
		"Policy is the candidate being tested. HPA is the historical production baseline.",
		"One evaluation means one Policy call",
		"## Did the Policy Stay Stable?",
		"Fewer target changes and direction reversals are better.",
		"## How Much Capacity Did the Policy Request?",
		"Two replicas for three hours equal six replica-hours.",
		"## When Did the Recommendation Change?",
		"Why this row starts",
		"## Run Identity",
	} {
		if !strings.Contains(reportText, expected) {
			t.Fatalf("Markdown report missing %q:\n%s", expected, markdown)
		}
	}
	for _, unwanted := range []string{"Event", "event", "AlwaysNoScale", "recall", "rejection", "Expected points"} {
		if strings.Contains(reportText, unwanted) {
			t.Fatalf("Markdown report contains Event-only or ambiguous term %q:\n%s", unwanted, markdown)
		}
	}

	jsonReport, err := os.ReadFile(firstJSON)
	if err != nil {
		t.Fatal(err)
	}
	for _, unwanted := range []string{"eventMetrics", "eventBaselines", "eventMatches", "eventsInWindow", "matchLeadSeconds"} {
		if strings.Contains(string(jsonReport), unwanted) {
			t.Fatalf("JSON report contains Event-only field %q:\n%s", unwanted, jsonReport)
		}
	}
}

func TestReplayReportShowsRecommendationGapReason(t *testing.T) {
	start := time.Date(2026, 8, 1, 0, 0, 0, 0, time.UTC)
	report := &ReplayReport{
		Dataset: ReplayDatasetIdentity{Window: O11YQueryWindow{Start: start, End: start.Add(10 * time.Minute)}},
		Episodes: []RecommendationEpisode{
			{StartAt: start, EndAt: start, DecisionCount: 1, StartReason: RecommendationStartInitial, Desired: Capacity{Tier: "fixed", Replicas: 1}},
			{StartAt: start.Add(10 * time.Minute), EndAt: start.Add(10 * time.Minute), DecisionCount: 1, StartReason: RecommendationStartAfterSkipped, Desired: Capacity{Tier: "fixed", Replicas: 1}},
		},
	}

	markdown := RenderReplayReportMarkdown(report)
	if !strings.Contains(markdown, "Resumed after skipped input") {
		t.Fatalf("Markdown report does not explain the episode gap:\n%s", markdown)
	}
}
