// This file verifies the combined report keeps point-in-time and replay results separate.
package evaluation

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

func TestOfflineEvaluationReportLeadsWithSeparateConclusions(t *testing.T) {
	start := time.Date(2026, 8, 1, 0, 0, 0, 0, time.UTC)
	report := &OfflineEvaluationReport{
		PolicyType: "CostOptimized",
		PointInTime: PointInTimeDecisionEvaluation{
			Candidate: SuiteMetrics{
				TotalCases:                  112,
				PassedCases:                 48,
				UsefulScaleOutCases:         31,
				UsefulScaleOutAccepted:      9,
				UnnecessaryScaleOutCases:    81,
				UnnecessaryScaleOutRejected: 41,
			},
			Baselines: []PointInTimeBaseline{
				{Name: "AlwaysNoScale", Metrics: SuiteMetrics{TotalCases: 112, PassedCases: 82, UsefulScaleOutCases: 31, UsefulScaleOutAccepted: 1, UnnecessaryScaleOutCases: 81, UnnecessaryScaleOutRejected: 81}},
				{Name: "AlwaysScaleOut", Metrics: SuiteMetrics{TotalCases: 112, PassedCases: 29, UsefulScaleOutCases: 31, UsefulScaleOutAccepted: 31, UnnecessaryScaleOutCases: 81}},
			},
		},
		Replay: &ReplayReport{
			Dataset: ReplayDatasetIdentity{
				Target: O11YTargetSpec{ClusterID: "cluster-1"},
				Window: O11YQueryWindow{Start: start, End: start.Add(7 * 24 * time.Hour)},
			},
			Summary: ReplaySummary{
				ScheduledPoints:                2017,
				EvaluatedPoints:                2006,
				SkippedPoints:                  11,
				HPAReferencePoints:             2006,
				TargetChanges:                  74,
				HPATargetChanges:               15,
				DirectionReversals:             57,
				HPADirectionReversals:          5,
				ComparableReplicaHourIntervals: 2005,
				HPAReplicaHours:                192.667,
				RecommendedReplicaHours:        185.250,
			},
		},
	}

	markdown := RenderOfflineEvaluationReportMarkdown(report)
	for _, expected := range []string{
		"# Offline Autoscaling Evaluation Report",
		"## Conclusion",
		"**Overall:** This candidate needs more tuning.",
		"**Point-in-time decisions:** The Policy made the expected horizontal action in **50 of 112 cases (44.6%)**. `AlwaysNoScale` did so in **82 of 112 cases (73.2%)**.",
		"**Continuous behavior:** The Policy changed its replica target **74 times**, compared with **15 times** for HPA. It reversed direction **57 times**, compared with **5 times** for HPA.",
		"**Capacity tendency:** The Policy requested **185.250 replica-hours**, **3.8% less** than HPA. This is not measured savings.",
		"## Point-in-Time Decision Evaluation: Was Each Decision Correct?",
		"Each case has its own `decisionAt` and calls the Policy once. Cases may use historical or manually constructed metrics, and are not limited to the replay period.",
		"| `CostOptimized` | 9/31 (29.0%) | 41/81 (50.6%) | 50/112 (44.6%) | 48/112 (42.9%) |",
		"Case labels are fixed expected outcomes from the case YAML files; this report does not infer them from metrics.",
		"## Continuous Replay: Did the Policy Behave Stably?",
		"The replay uses one continuous period: `2026-08-01T00:00:00Z` to `2026-08-08T00:00:00Z`.",
		"Replica-hours show capacity tendency only because replay decisions were not executed.",
	} {
		if !strings.Contains(markdown, expected) {
			t.Fatalf("offline report missing %q:\n%s", expected, markdown)
		}
	}

	conclusion := strings.Index(markdown, "## Conclusion")
	pointInTime := strings.Index(markdown, "## Point-in-Time Decision Evaluation")
	replay := strings.Index(markdown, "## Continuous Replay")
	if conclusion < 0 || pointInTime < conclusion || replay < pointInTime {
		t.Fatalf("report sections are not conclusion, point-in-time, replay:\n%s", markdown)
	}
	for _, unwanted := range []string{"Event Evaluation", "event evaluation", "human-reviewed", "events in this replay window"} {
		if strings.Contains(markdown, unwanted) {
			t.Fatalf("report contains ambiguous term %q:\n%s", unwanted, markdown)
		}
	}
}

func TestWriteOfflineEvaluationReportUsesRequestedFileName(t *testing.T) {
	outputDir := t.TempDir()
	path, err := WriteOfflineEvaluationReport(outputDir, &OfflineEvaluationReport{Replay: &ReplayReport{}})
	if err != nil {
		t.Fatalf("WriteOfflineEvaluationReport(): %v", err)
	}
	want := filepath.Join(outputDir, "offline-evalution-report.md")
	if path != want {
		t.Fatalf("path = %q, want %q", path, want)
	}
	if _, err := os.Stat(path); err != nil {
		t.Fatalf("stat offline report: %v", err)
	}
}
