package engine

import (
	"context"
	"os"
	"strings"
	"testing"

	"github.com/Armur-Ai/Pentest-Swarm-AI/internal/pipeline"
)

// Every demo target must replay a real campaign offline: at least one graded
// finding, attack chains carrying planner reasoning, and a completion
// milestone — and the selector must honour the chosen target.
func TestDemoScenariosAllReplay(t *testing.T) {
	os.Setenv("PENTESTSWARM_DEMO_SPEED", "200")
	defer os.Unsetenv("PENTESTSWARM_DEMO_SPEED")

	for _, key := range DemoScenarioKeys() {
		t.Run(key, func(t *testing.T) {
			var findings, chains, reasoned int
			var sawComplete bool
			err := RunDemoReplay(context.Background(), CampaignConfig{DemoTarget: key}, func(e pipeline.CampaignEvent) {
				switch e.EventType {
				case pipeline.EventFindingDiscovered:
					findings++
				case pipeline.EventChainStarted:
					chains++
					if strings.Contains(string(e.Data), `"reasoning"`) &&
						!strings.Contains(string(e.Data), `"reasoning":""`) {
						reasoned++
					}
				case pipeline.EventMilestone:
					if strings.Contains(e.Detail, "campaign complete") {
						sawComplete = true
					}
				}
			})
			if err != nil {
				t.Fatalf("%s: %v", key, err)
			}
			if findings == 0 {
				t.Errorf("%s: no findings", key)
			}
			if chains == 0 {
				t.Errorf("%s: no attack chains", key)
			}
			if reasoned == 0 {
				t.Errorf("%s: no chain carried planner reasoning", key)
			}
			if !sawComplete {
				t.Errorf("%s: no completion milestone", key)
			}
		})
	}
}

// An unknown target falls back to crAPI rather than erroring or emitting nothing.
func TestDemoUnknownTargetFallsBack(t *testing.T) {
	os.Setenv("PENTESTSWARM_DEMO_SPEED", "200")
	defer os.Unsetenv("PENTESTSWARM_DEMO_SPEED")
	var findings int
	_ = RunDemoReplay(context.Background(), CampaignConfig{DemoTarget: "does-not-exist"}, func(e pipeline.CampaignEvent) {
		if e.EventType == pipeline.EventFindingDiscovered {
			findings++
		}
	})
	if findings == 0 {
		t.Fatal("unknown target produced no findings (expected crAPI fallback)")
	}
}
