package openai

import (
	"net/http"
	"strings"
	"testing"
)

func TestHotPathReviewPass(t *testing.T) {
	for _, endpoint := range []string{"openai", "anthropic"} {
		endpoint := endpoint
		t.Run(endpoint, func(t *testing.T) {
			fixture := newScriptedLightFixture(t, endpoint, false)
			final := fixture.run()
			if final.Code != http.StatusOK || !strings.Contains(final.Body.String(), "PASS and DEFECT prose") {
				t.Fatalf("review pass response: status=%d body=%s", final.Code, final.Body.String())
			}
			fixture.assertCleanupCommitted(7)
		})
	}
}

func TestHotPathReviewDefectRepair(t *testing.T) {
	for _, endpoint := range []string{"openai", "anthropic"} {
		endpoint := endpoint
		t.Run(endpoint, func(t *testing.T) {
			fixture := newScriptedLightFixture(t, endpoint, true)
			final := fixture.run()
			if final.Code != http.StatusOK || !strings.Contains(final.Body.String(), "repair-complete-visible") {
				t.Fatalf("review repair response: status=%d body=%s", final.Code, final.Body.String())
			}
			fixture.assertCleanupCommitted(8)

			// A completed review has no second tool frontier. Replaying the last
			// repair result is rejected before another provider submission.
			before := len(fixture.service.snapshots())
			replay := fixture.request()
			if replay.Code != http.StatusBadRequest {
				t.Fatalf("second review replay status=%d body=%s", replay.Code, replay.Body.String())
			}
			if after := len(fixture.service.snapshots()); after != before {
				t.Fatalf("second review dispatched provider calls: before=%d after=%d", before, after)
			}
		})
	}
}

func TestHotPathReviewStructureIgnoresProseVerdict(t *testing.T) {
	completion := normalizedStageOutput{Content: "DEFECT FAIL words do not control state"}
	evidence := hotPathReviewEvidence{planRead: true, reviewRead: true, inspected: true}
	if kind, cleanup, err := classifyHotPathReviewOutput("req_review", hotPathPhaseReviewActive, completion, evidence); err != nil || kind != "" || !cleanup {
		t.Fatalf("completion structure did not pass: kind=%q cleanup=%t err=%v", kind, cleanup, err)
	}
	repair := normalizedStageOutput{
		Content:   "PASS words do not control state",
		ToolCalls: []normalizedToolCall{{ID: "provider_repair", Name: "run_command", Arguments: map[string]any{"command": "go test"}}},
	}
	if kind, cleanup, err := classifyHotPathReviewOutput("req_review", hotPathPhaseReviewActive, repair, evidence); err != nil || kind != hotPathPendingReviewRepair || cleanup {
		t.Fatalf("repair structure did not stay active: kind=%q cleanup=%t err=%v", kind, cleanup, err)
	}
}

func TestHotPathReviewRequiresInspectionAndNonEmptyTerminal(t *testing.T) {
	completion := normalizedStageOutput{Content: "reviewed"}
	if _, _, err := classifyHotPathReviewOutput("req_review", hotPathPhaseReviewActive, completion, hotPathReviewEvidence{}); err == nil || !strings.Contains(err.Error(), "artifact reads") {
		t.Fatalf("skipped inspection error = %v", err)
	}
	evidence := hotPathReviewEvidence{planRead: true, reviewRead: true, inspected: true}
	if _, _, err := classifyHotPathReviewOutput("req_review", hotPathPhaseReviewActive, normalizedStageOutput{}, evidence); err == nil || !strings.Contains(err.Error(), "non-empty") {
		t.Fatalf("empty terminal error = %v", err)
	}
	reservedRepair := normalizedStageOutput{ToolCalls: []normalizedToolCall{{
		ID: "provider_second_review", Name: "read_file",
		Arguments: map[string]any{"path": newReservedPaths("req_review").ReviewPath},
	}}}
	if _, _, err := classifyHotPathReviewOutput("req_review", hotPathPhaseReviewRepair, reservedRepair, evidence); err == nil || !strings.Contains(err.Error(), "second review cycle") {
		t.Fatalf("second review cycle error = %v", err)
	}
}
