package openai

import (
	"bufio"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"

	iop "iop/proto/gen/iop"
)

type hotPathAnthropicSSEEvent struct {
	name    string
	payload map[string]any
}

func TestHotPathAnthropicDirectStreamCodec(t *testing.T) {
	tests := []struct {
		name, profile, responseID, providerToolID, providerBody string
		wantSignature                                           string
	}{
		{
			name: "native provider", profile: "anthropic", responseID: "msg-anthropic-gate", providerToolID: "provider-native-tool",
			providerBody: strings.Join([]string{
				`data: {"type":"message_start","message":{"id":"msg-anthropic-gate","type":"message","role":"assistant","content":[],"usage":{"input_tokens":9,"output_tokens":0,"cache_read_input_tokens":2}}}`,
				`data: {"type":"content_block_start","index":0,"content_block":{"type":"thinking","thinking":"","signature":""}}`,
				`data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"plan "}}`,
				`data: {"type":"content_block_delta","index":0,"delta":{"type":"thinking_delta","thinking":"now"}}`,
				`data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"sig-native"}}`,
				`data: {"type":"content_block_stop","index":0}`,
				`data: {"type":"content_block_start","index":1,"content_block":{"type":"text","text":""}}`,
				`data: {"type":"content_block_delta","index":1,"delta":{"type":"text_delta","text":"alpha "}}`,
				`data: {"type":"content_block_delta","index":1,"delta":{"type":"text_delta","text":"omega"}}`,
				`data: {"type":"content_block_stop","index":1}`,
				`data: {"type":"content_block_start","index":2,"content_block":{"type":"tool_use","id":"provider-native-tool","name":"read_file","input":{}}}`,
				`data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"{\"path\":"}}`,
				`data: {"type":"content_block_delta","index":2,"delta":{"type":"input_json_delta","partial_json":"\"README.md\"}"}}`,
				`data: {"type":"content_block_stop","index":2}`,
				`data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":7}}`,
				`data: {"type":"message_stop"}`, "",
			}, "\n\n"),
			wantSignature: "sig-native",
		},
		{
			name: "OpenAI provider", profile: "openai", responseID: "chatcmpl-anthropic-gate", providerToolID: "provider-openai-tool",
			providerBody: strings.Join([]string{
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"reasoning_content":"plan "},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"reasoning_content":"now"},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"content":"alpha "},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"content":"omega"},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"provider-openai-tool","type":"function","function":{"name":"read_file","arguments":"{\"path\":"}}]},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"README.md\"}"}}]},"finish_reason":null}]}`,
				`data: {"id":"chatcmpl-anthropic-gate","created":1777002001,"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":9,"completion_tokens":7,"total_tokens":16}}`,
				`data: [DONE]`, "",
			}, "\n\n"),
		},
	}

	for _, test := range tests {
		test := test
		t.Run(test.name, func(t *testing.T) {
			var decoded normalizedStageOutput
			var decodeErr error
			if test.profile == "anthropic" {
				decoded, decodeErr = decodeAnthropicPresetSSE([]byte(test.providerBody))
			} else {
				decoded, decodeErr = decodeOpenAIPresetSSE([]byte(test.providerBody))
			}
			if decodeErr != nil || len(decoded.ToolCalls) != 1 || len(decoded.Deltas) != 6 {
				t.Fatalf("provider fixture decode: output=%+v err=%v", decoded, decodeErr)
			}
			candidate := anthropicTestCandidate(t, test.profile)
			fragments := splitAnthropicFixture([]byte(test.providerBody), 13, 79, 211, len(test.providerBody)-17)
			contentType := "text/event-stream"
			srv, fake := newHotPathHandlerServer(t, candidate, anthropicTunnelFrames(http.StatusOK, contentType, fragments...))
			response := serveHotPathAnthropicBody(t, srv, `{"model":"virtual-model","max_tokens":64,"messages":[{"role":"user","content":"hello"}],"tools":[{"name":"read_file","description":"read","input_schema":{"type":"object"}}],"stream":true}`)
			if response.Code != http.StatusOK || response.Header().Get("Content-Type") != "text/event-stream" {
				t.Fatalf("response mismatch: status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String())
			}

			events := decodeHotPathAnthropicSSE(t, response.Body.String())
			assertHotPathAnthropicDirectEvents(t, events, test.responseID, test.wantSignature)
			if fake.poolSubmitCountSnapshot() != 1 {
				t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
			}
			assertHotPathWaiting(t, srv, test.responseID+"-tool-1", test.providerToolID)
		})
	}
}

func TestHotPathAnthropicDirectStreamPreservesEmptyToolInput(t *testing.T) {
	providerBody := strings.Join([]string{
		`data: {"type":"message_start","message":{"id":"msg-empty-tool","type":"message","role":"assistant","content":[],"usage":{"input_tokens":5,"output_tokens":0}}}`,
		`data: {"type":"content_block_start","index":0,"content_block":{"type":"tool_use","id":"provider-zero-arg-tool","name":"list_dir","input":{}}}`,
		`data: {"type":"content_block_stop","index":0}`,
		`data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"output_tokens":4}}`,
		`data: {"type":"message_stop"}`, "",
	}, "\n\n")

	candidate := anthropicTestCandidate(t, "anthropic")
	contentType := "text/event-stream"
	srv, fake := newHotPathHandlerServer(t, candidate, anthropicTunnelFrames(http.StatusOK, contentType, []byte(providerBody)))
	response := serveHotPathAnthropicBody(t, srv, `{"model":"virtual-model","max_tokens":64,"messages":[{"role":"user","content":"list files"}],"tools":[{"name":"list_dir","description":"list","input_schema":{"type":"object"}}],"stream":true}`)
	if response.Code != http.StatusOK || response.Header().Get("Content-Type") != "text/event-stream" {
		t.Fatalf("response mismatch: status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String())
	}

	events := decodeHotPathAnthropicSSE(t, response.Body.String())
	wantNames := []string{
		"message_start",
		"content_block_start", "content_block_delta", "content_block_stop",
		"message_delta", "message_stop",
	}
	if got := hotPathAnthropicEventNames(events); strings.Join(got, ",") != strings.Join(wantNames, ",") {
		t.Fatalf("event order=%v, want %v; body=%s", got, wantNames, response.Body.String())
	}

	var toolID, toolName, partialJSON string
	var deltaCount int
	for _, event := range events {
		switch event.name {
		case "content_block_start":
			block := hotPathAnthropicMap(t, event.payload["content_block"])
			if block["type"] == "tool_use" {
				toolID, _ = block["id"].(string)
				toolName, _ = block["name"].(string)
			}
		case "content_block_delta":
			delta := hotPathAnthropicMap(t, event.payload["delta"])
			if delta["type"] == "input_json_delta" {
				deltaCount++
				partialJSON, _ = delta["partial_json"].(string)
			}
		}
	}

	if toolID != "msg-empty-tool-tool-1" || toolName != "list_dir" || deltaCount != 1 || partialJSON != "{}" {
		t.Fatalf("empty tool preservation mismatch: toolID=%q toolName=%q deltaCount=%d partialJSON=%q", toolID, toolName, deltaCount, partialJSON)
	}

	if fake.poolSubmitCountSnapshot() != 1 {
		t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
	}
	assertHotPathWaiting(t, srv, "msg-empty-tool-tool-1", "provider-zero-arg-tool")
}

func TestHotPathAnthropicLightStreamAggregatesStages(t *testing.T) {
	fixture := newScriptedLightFixture(t, "anthropic", false)
	fixture.service.responses[4] = func(string) string {
		return scriptedLightCompletionWithUsage("anthropic", "local-visible", "local-reason", 5, 3)
	}
	fixture.service.responses[5] = func(requestID string) string {
		return scriptedReviewReadsAndInspectionWithUsage(requestID, 7, 4)
	}

	prepare := fixture.request()
	fixture.consumeToolResponse(prepare, []string{`{"written":true}`})
	pair := fixture.request()
	fixture.consumeToolResponse(pair, []string{`{"written":true}`, `{"written":true}`})
	localRead := fixture.request()
	fixture.consumeToolResponse(localRead, []string{`{"written":true}`})
	localWork := fixture.request()
	fixture.consumeToolResponse(localWork, []string{`{"ok":true}`})
	workerReview := fixture.request()
	fixture.consumeToolResponse(workerReview, []string{`{"written":true}`})

	before := len(fixture.service.snapshots())
	response := fixture.requestWithOptions(64, true)
	if response.Code != http.StatusOK {
		t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
	}
	if got := len(fixture.service.snapshots()) - before; got != 1 {
		t.Fatalf("same-turn provider stages=%d, want 1", got)
	}
	requests := fixture.service.snapshots()
	assertCapturedHotPathBudget(t, requests[len(requests)-1], fixture.service.candidate, 64)
	events := decodeHotPathAnthropicSSE(t, response.Body.String())
	assertHotPathAnthropicBlockIndexes(t, events, 5)

	wantNames := []string{
		"message_start",
		"content_block_start", "content_block_delta", "content_block_delta", "content_block_stop",
		"content_block_start", "content_block_delta", "content_block_stop",
		"content_block_start", "content_block_delta", "content_block_stop",
		"content_block_start", "content_block_delta", "content_block_stop",
		"content_block_start", "content_block_delta", "content_block_stop",
		"message_delta", "message_stop",
	}
	if got := hotPathAnthropicEventNames(events); strings.Join(got, ",") != strings.Join(wantNames, ",") {
		t.Fatalf("event order=%v, want %v; body=%s", got, wantNames, response.Body.String())
	}
	startMessage := hotPathAnthropicMap(t, events[0].payload["message"])
	requestID, snapshot := soleHotPathSnapshot(t, fixture.server)
	if startMessage["id"] != "msg-review-inspection" || startMessage["id"] == requestID || startMessage["model"] != "virtual-model" {
		t.Fatalf("outer identity mismatch: message=%+v logical_request=%s", startMessage, requestID)
	}

	wantKinds := []string{"thinking", "text", "tool_use", "tool_use", "tool_use"}
	var gotKinds, thinking, text []string
	var toolIDs, toolNames, toolArgs []string
	var stopReason string
	for _, event := range events {
		switch event.name {
		case "content_block_start":
			block := hotPathAnthropicMap(t, event.payload["content_block"])
			gotKinds = append(gotKinds, fmt.Sprint(block["type"]))
			if block["type"] == "tool_use" {
				toolIDs = append(toolIDs, fmt.Sprint(block["id"]))
				toolNames = append(toolNames, fmt.Sprint(block["name"]))
			}
		case "content_block_delta":
			delta := hotPathAnthropicMap(t, event.payload["delta"])
			switch delta["type"] {
			case "thinking_delta":
				thinking = append(thinking, fmt.Sprint(delta["thinking"]))
			case "text_delta":
				text = append(text, fmt.Sprint(delta["text"]))
			case "input_json_delta":
				toolArgs = append(toolArgs, fmt.Sprint(delta["partial_json"]))
			}
		case "message_delta":
			delta := hotPathAnthropicMap(t, event.payload["delta"])
			stopReason, _ = delta["stop_reason"].(string)
			usage := hotPathAnthropicMap(t, event.payload["usage"])
			if usage["input_tokens"] != float64(7) || usage["output_tokens"] != float64(4) {
				t.Fatalf("review usage=%+v, want input=7 output=4", usage)
			}
		}
	}
	if strings.Join(gotKinds, ",") != strings.Join(wantKinds, ",") ||
		strings.Join(thinking, "") != "review-reason" || strings.Join(text, "") != "review-visible" ||
		strings.Join(toolNames, ",") != "read_file,read_file,run_command" || len(toolArgs) != 3 || stopReason != "tool_use" {
		t.Fatalf("multi-stage output mismatch: kinds=%v thinking=%v text=%v tool=%q/%q/%q stop=%q body=%s",
			gotKinds, thinking, text, toolIDs, toolNames, toolArgs, stopReason, response.Body.String())
	}
	if len(snapshot.ExpectedCallIDs) != 3 {
		t.Fatalf("tool correlation mismatch: tools=%q snapshot=%+v", toolIDs, snapshot)
	}
	if strings.Join(toolIDs, ",") != "msg-review-inspection-tool-1,msg-review-inspection-tool-2,msg-review-inspection-tool-3" {
		t.Fatalf("public tool namespace mismatch: tools=%q body=%s", toolIDs, response.Body.String())
	}
}

func TestHotPathAnthropicToolIDsAreMonotonic(t *testing.T) {
	candidate := anthropicTestCandidate(t, "anthropic")
	providerBody := []byte(`{"id":"msg-anthropic-tools","type":"message","role":"assistant","content":[{"type":"tool_use","id":"provider-tool-a","name":"read_file","input":{"path":"a"}},{"type":"tool_use","id":"provider-tool-b","name":"read_file","input":{"path":"b"}}],"stop_reason":"tool_use","usage":{"input_tokens":4,"output_tokens":3}}`)
	srv, _ := newHotPathHandlerServer(t, candidate, anthropicTunnelFrames(http.StatusOK, "application/json", providerBody))
	response := serveHotPathAnthropic(t, srv, true)
	if response.Code != http.StatusOK {
		t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
	}
	events := decodeHotPathAnthropicSSE(t, response.Body.String())
	assertHotPathAnthropicBlockIndexes(t, events, 2)
	var toolIDs []string
	for _, event := range events {
		if event.name != "content_block_start" {
			continue
		}
		block := hotPathAnthropicMap(t, event.payload["content_block"])
		if block["type"] == "tool_use" {
			toolIDs = append(toolIDs, fmt.Sprint(block["id"]))
		}
	}
	wantIDs := []string{"msg-anthropic-tools-tool-1", "msg-anthropic-tools-tool-2"}
	if fmt.Sprint(toolIDs) != fmt.Sprint(wantIDs) {
		t.Fatalf("tool ids=%v, want %v; body=%s", toolIDs, wantIDs, response.Body.String())
	}
	requestID, snapshot := soleHotPathSnapshot(t, srv)
	expectedSet := make(map[string]bool, len(snapshot.ExpectedCallIDs))
	for _, id := range snapshot.ExpectedCallIDs {
		expectedSet[id] = true
	}
	if len(snapshot.ExpectedCallIDs) != len(wantIDs) || !expectedSet[wantIDs[0]] || !expectedSet[wantIDs[1]] {
		t.Fatalf("expected caller ids=%v, want %v", snapshot.ExpectedCallIDs, wantIDs)
	}
	srv.requestCoordinator.mu.Lock()
	record := srv.requestCoordinator.requests[requestID]
	mapping := map[string]string{}
	if record != nil {
		for _, id := range wantIDs {
			mapping[id] = record.publicToProvider[id]
		}
	}
	srv.requestCoordinator.mu.Unlock()
	if mapping[wantIDs[0]] != "provider-tool-a" || mapping[wantIDs[1]] != "provider-tool-b" {
		t.Fatalf("provider tool mapping=%v", mapping)
	}
}

func TestHotPathAnthropicCallerCapAndNonStream(t *testing.T) {
	candidate := anthropicTestCandidate(t, "anthropic")
	providerBody := []byte(`{"id":"msg-anthropic-cap","type":"message","role":"assistant","content":[{"type":"text","text":"abcdefghij"}],"stop_reason":"end_turn","usage":{"input_tokens":3,"output_tokens":2}}`)
	srv, fake := newHotPathHandlerServer(t, candidate, anthropicTunnelFrames(http.StatusOK, "application/json", providerBody[:31], providerBody[31:]))
	response := serveHotPathAnthropicBody(t, srv, `{"model":"virtual-model","max_tokens":2,"messages":[{"role":"user","content":"cap"}],"stream":false}`)
	if response.Code != http.StatusOK {
		t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
	}
	var decoded struct {
		ID         string            `json:"id"`
		Model      string            `json:"model"`
		Content    []json.RawMessage `json:"content"`
		StopReason string            `json:"stop_reason"`
		Usage      anthropicUsage    `json:"usage"`
	}
	if err := json.Unmarshal(response.Body.Bytes(), &decoded); err != nil {
		t.Fatal(err)
	}
	if decoded.ID != "msg-anthropic-cap" || decoded.Model != "virtual-model" || decoded.StopReason != "end_turn" ||
		decoded.Usage.InputTokens != 3 || decoded.Usage.OutputTokens != 2 || len(decoded.Content) != 1 {
		t.Fatalf("non-stream envelope mismatch: %+v body=%s", decoded, response.Body.String())
	}
	var textBlock struct {
		Type string `json:"type"`
		Text string `json:"text"`
	}
	if err := json.Unmarshal(decoded.Content[0], &textBlock); err != nil || textBlock.Type != "text" || textBlock.Text != "abcdefghij" {
		t.Fatalf("provider-token content=%+v err=%v", textBlock, err)
	}
	if fake.poolSubmitCountSnapshot() != 1 {
		t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
	}
	var upstream map[string]any
	if bodies := fake.tunnelBodiesSnapshot(); len(bodies) != 1 {
		t.Fatalf("upstream body count=%d, want 1", len(bodies))
	} else if err := json.Unmarshal(bodies[0], &upstream); err != nil || upstream["max_tokens"] != float64(2) {
		t.Fatalf("upstream max_tokens was not retained: body=%s decoded=%+v err=%v", bodies[0], upstream, err)
	}
	assertHotPathTerminal(t, srv)
}

func TestHotPathAnthropicErrorBoundaries(t *testing.T) {
	t.Run("required max tokens fails before dispatch", func(t *testing.T) {
		candidate := anthropicTestCandidate(t, "anthropic")
		srv, fake := newHotPathHandlerServer(t, candidate, nil)
		response := serveHotPathAnthropicBody(t, srv, `{"model":"virtual-model","messages":[{"role":"user","content":"missing cap"}],"stream":true}`)
		if response.Code != http.StatusBadRequest || !strings.Contains(response.Body.String(), `"type":"invalid_request_error"`) ||
			strings.Contains(response.Body.String(), "message_start") {
			t.Fatalf("pre-dispatch validation mismatch: status=%d body=%s", response.Code, response.Body.String())
		}
		if fake.poolSubmitCountSnapshot() != 0 {
			t.Fatalf("selector submissions=%d, want 0", fake.poolSubmitCountSnapshot())
		}
	})

	t.Run("provider error before commit is JSON", func(t *testing.T) {
		candidate := anthropicTestCandidate(t, "anthropic")
		frames := make(chan *iop.ProviderTunnelFrame, 2)
		frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: http.StatusBadGateway}
		frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true}
		close(frames)
		srv, fake := newHotPathHandlerServer(t, candidate, frames)
		response := serveHotPathAnthropic(t, srv, true)
		if response.Code != http.StatusBadGateway || !strings.Contains(response.Body.String(), `"type":"api_error"`) ||
			strings.Contains(response.Body.String(), "message_start") || strings.Contains(response.Body.String(), "message_stop") {
			t.Fatalf("pre-commit error mismatch: status=%d body=%s", response.Code, response.Body.String())
		}
		if fake.poolSubmitCountSnapshot() != 1 {
			t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
		}
		assertHotPathTerminal(t, srv)
	})

	t.Run("missing provider identity fails before commit", func(t *testing.T) {
		candidate := anthropicTestCandidate(t, "anthropic")
		body := []byte("data: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"unsafe\"}}\n\n")
		srv, fake := newHotPathHandlerServer(t, candidate, anthropicTunnelFrames(http.StatusOK, "text/event-stream", body))
		response := serveHotPathAnthropic(t, srv, true)
		if response.Code != http.StatusBadGateway || !strings.Contains(response.Body.String(), `"type":"api_error"`) ||
			strings.Contains(response.Body.String(), "message_start") {
			t.Fatalf("missing-identity failure mismatch: status=%d body=%s", response.Code, response.Body.String())
		}
		if fake.poolSubmitCountSnapshot() != 1 {
			t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
		}
	})

	t.Run("conflicting provider identity fails after commit", func(t *testing.T) {
		candidate := anthropicTestCandidate(t, "anthropic")
		frames := make(chan *iop.ProviderTunnelFrame, 4)
		frames <- &iop.ProviderTunnelFrame{
			Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: http.StatusOK,
			Headers: map[string]string{"Content-Type": "text/event-stream"},
		}
		frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(strings.Join([]string{
			`data: {"type":"message_start","message":{"id":"msg-first","usage":{"input_tokens":1}}}`,
			`data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":"visible"}}`, "",
		}, "\n\n"))}
		frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY,
			Body: []byte("data: {\"type\":\"message_start\",\"message\":{\"id\":\"msg-conflict\",\"usage\":{\"input_tokens\":1}}}\n\n")}
		frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true}
		close(frames)
		srv, _ := newHotPathHandlerServer(t, candidate, frames)
		response := serveHotPathAnthropic(t, srv, true)
		events := decodeHotPathAnthropicSSE(t, response.Body.String())
		if got := hotPathAnthropicEventNames(events); strings.Join(got, ",") != "message_start,content_block_start,content_block_delta,error" ||
			strings.Contains(response.Body.String(), "msg-conflict") || strings.Contains(response.Body.String(), "message_stop") {
			t.Fatalf("conflicting-identity terminal mismatch: events=%v body=%s", got, response.Body.String())
		}
	})
}

func TestHotPathAnthropicFlushesBeforeEndAndErrorsAfterCommit(t *testing.T) {
	candidate := anthropicTestCandidate(t, "anthropic")
	frames := make(chan *iop.ProviderTunnelFrame, 4)
	frames <- &iop.ProviderTunnelFrame{
		Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: http.StatusOK,
		Headers: map[string]string{"Content-Type": "text/event-stream"}, RunId: "run-anthropic-live",
	}
	frames <- &iop.ProviderTunnelFrame{
		Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, RunId: "run-anthropic-live",
		Body: []byte(strings.Join([]string{
			`data: {"type":"message_start","message":{"id":"msg-anthropic-live","usage":{"input_tokens":3,"output_tokens":0}}}`,
			`data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}`,
			`data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"early-visible"}}`, "",
		}, "\n\n")),
	}
	srv, fake := newHotPathHandlerServer(t, candidate, frames)
	httpServer := httptest.NewServer(srv.routes())
	defer httpServer.Close()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	body := `{"model":"virtual-model","max_tokens":64,"messages":[{"role":"user","content":"flush"}],"stream":true}`
	request, err := http.NewRequestWithContext(ctx, http.MethodPost, httpServer.URL+"/v1/messages", strings.NewReader(body))
	if err != nil {
		t.Fatal(err)
	}
	request.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		t.Fatalf("stream request did not flush before provider END: %v", err)
	}
	defer response.Body.Close()
	reader := bufio.NewReader(response.Body)
	var early strings.Builder
	for range 3 {
		frame, err := readHotPathSSEFrame(reader)
		if err != nil {
			t.Fatalf("read pre-END Anthropic frame: %v", err)
		}
		early.WriteString(frame)
	}
	if response.StatusCode != http.StatusOK || !strings.Contains(early.String(), `"id":"msg-anthropic-live"`) ||
		!strings.Contains(early.String(), `"text":"early-visible"`) || strings.Contains(early.String(), "message_stop") {
		t.Fatalf("pre-END flush mismatch: status=%d body=%s", response.StatusCode, early.String())
	}
	frames <- &iop.ProviderTunnelFrame{
		Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_ERROR, Error: "provider failed", RunId: "run-anthropic-live",
	}
	close(frames)
	rest, err := io.ReadAll(reader)
	if err != nil {
		t.Fatalf("read post-commit error: %v", err)
	}
	wire := early.String() + string(rest)
	events := decodeHotPathAnthropicSSE(t, wire)
	if got := hotPathAnthropicEventNames(events); strings.Join(got, ",") != "message_start,content_block_start,content_block_delta,error" ||
		strings.Count(wire, "event: error") != 1 || strings.Contains(wire, "message_delta") || strings.Contains(wire, "message_stop") {
		t.Fatalf("post-commit provider error mismatch: events=%v body=%s", got, wire)
	}
	if fake.poolSubmitCountSnapshot() != 1 {
		t.Fatalf("selector submissions=%d, want 1", fake.poolSubmitCountSnapshot())
	}
}

func serveHotPathAnthropicBody(t *testing.T, srv *Server, body string) *httptest.ResponseRecorder {
	t.Helper()
	request := httptest.NewRequest(http.MethodPost, "/v1/messages", strings.NewReader(body))
	request.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
	response := httptest.NewRecorder()
	srv.routes().ServeHTTP(response, request)
	return response
}

func decodeHotPathAnthropicSSE(t *testing.T, body string) []hotPathAnthropicSSEEvent {
	t.Helper()
	body = strings.ReplaceAll(body, "\r\n", "\n")
	var events []hotPathAnthropicSSEEvent
	for _, frame := range strings.Split(body, "\n\n") {
		frame = strings.TrimSpace(frame)
		if frame == "" {
			continue
		}
		var name string
		var data []string
		for _, line := range strings.Split(frame, "\n") {
			switch {
			case strings.HasPrefix(line, "event:"):
				name = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
			case strings.HasPrefix(line, "data:"):
				data = append(data, strings.TrimSpace(strings.TrimPrefix(line, "data:")))
			}
		}
		if name == "" || len(data) == 0 {
			t.Fatalf("malformed Anthropic SSE frame %q", frame)
		}
		var payload map[string]any
		if err := json.Unmarshal([]byte(strings.Join(data, "\n")), &payload); err != nil {
			t.Fatalf("decode Anthropic SSE %q: %v", frame, err)
		}
		if payload["type"] != name {
			t.Fatalf("event/type mismatch: event=%q payload=%+v", name, payload)
		}
		events = append(events, hotPathAnthropicSSEEvent{name: name, payload: payload})
	}
	return events
}

func hotPathAnthropicEventNames(events []hotPathAnthropicSSEEvent) []string {
	names := make([]string, 0, len(events))
	for _, event := range events {
		names = append(names, event.name)
	}
	return names
}

func hotPathAnthropicMap(t *testing.T, value any) map[string]any {
	t.Helper()
	mapped, ok := value.(map[string]any)
	if !ok {
		t.Fatalf("value is not an object: %#v", value)
	}
	return mapped
}

func assertHotPathAnthropicDirectEvents(t *testing.T, events []hotPathAnthropicSSEEvent, responseID, signature string) {
	t.Helper()
	assertHotPathAnthropicBlockIndexes(t, events, 3)
	wantNames := []string{
		"message_start",
		"content_block_start", "content_block_delta", "content_block_delta",
	}
	if signature != "" {
		wantNames = append(wantNames, "content_block_delta")
	}
	wantNames = append(wantNames,
		"content_block_stop",
		"content_block_start", "content_block_delta", "content_block_delta", "content_block_stop",
		"content_block_start", "content_block_delta", "content_block_delta", "content_block_stop",
		"message_delta", "message_stop",
	)
	if got := hotPathAnthropicEventNames(events); strings.Join(got, ",") != strings.Join(wantNames, ",") {
		t.Fatalf("event order=%v, want %v", got, wantNames)
	}
	message := hotPathAnthropicMap(t, events[0].payload["message"])
	if message["id"] != responseID || message["model"] != "virtual-model" {
		t.Fatalf("message_start mismatch: %+v", message)
	}
	if signature != "" {
		startUsage := hotPathAnthropicMap(t, message["usage"])
		if startUsage["input_tokens"] != float64(9) {
			t.Fatalf("message_start usage mismatch: %+v", message)
		}
	}

	wantKinds := []string{"thinking", "text", "tool_use"}
	var kinds, thinking, text, toolFragments []string
	var toolID, toolName, stopReason, gotSignature string
	for _, event := range events {
		switch event.name {
		case "content_block_start":
			block := hotPathAnthropicMap(t, event.payload["content_block"])
			kinds = append(kinds, fmt.Sprint(block["type"]))
			if block["type"] == "tool_use" {
				toolID, _ = block["id"].(string)
				toolName, _ = block["name"].(string)
			}
		case "content_block_delta":
			delta := hotPathAnthropicMap(t, event.payload["delta"])
			switch delta["type"] {
			case "thinking_delta":
				thinking = append(thinking, fmt.Sprint(delta["thinking"]))
			case "text_delta":
				text = append(text, fmt.Sprint(delta["text"]))
			case "input_json_delta":
				toolFragments = append(toolFragments, fmt.Sprint(delta["partial_json"]))
			case "signature_delta":
				gotSignature, _ = delta["signature"].(string)
			}
		case "message_delta":
			delta := hotPathAnthropicMap(t, event.payload["delta"])
			stopReason, _ = delta["stop_reason"].(string)
			usage := hotPathAnthropicMap(t, event.payload["usage"])
			if usage["input_tokens"] != float64(9) || usage["output_tokens"] != float64(7) {
				t.Fatalf("terminal usage=%+v, want input=9 output=7", usage)
			}
		}
	}
	if strings.Join(kinds, ",") != strings.Join(wantKinds, ",") || strings.Join(thinking, "") != "plan now" ||
		strings.Join(text, "") != "alpha omega" || strings.Join(toolFragments, "") != `{"path":"README.md"}` ||
		len(toolFragments) != 2 || toolID != responseID+"-tool-1" || toolName != "read_file" ||
		stopReason != "tool_use" || gotSignature != signature {
		t.Fatalf("stream aggregate mismatch: kinds=%v thinking=%v text=%v tool=%q/%q/%v stop=%q signature=%q",
			kinds, thinking, text, toolID, toolName, toolFragments, stopReason, gotSignature)
	}
}

func assertHotPathAnthropicBlockIndexes(t *testing.T, events []hotPathAnthropicSSEEvent, wantBlocks int) {
	t.Helper()
	nextStart := 0
	active := -1
	for _, event := range events {
		switch event.name {
		case "content_block_start":
			index := int(event.payload["index"].(float64))
			if active != -1 || index != nextStart {
				t.Fatalf("non-monotonic block start: active=%d index=%d next=%d", active, index, nextStart)
			}
			active = index
			nextStart++
		case "content_block_delta":
			index := int(event.payload["index"].(float64))
			if index != active {
				t.Fatalf("block delta index=%d, active=%d", index, active)
			}
		case "content_block_stop":
			index := int(event.payload["index"].(float64))
			if index != active {
				t.Fatalf("block stop index=%d, active=%d", index, active)
			}
			active = -1
		}
	}
	if active != -1 || nextStart != wantBlocks {
		t.Fatalf("block boundary mismatch: active=%d starts=%d want=%d", active, nextStart, wantBlocks)
	}
}
