package api

import (
	"context"
	"io"
	"net/http"
	"strings"
	"sync/atomic"
	"testing"
	"time"
)

type roundTripFunc func(*http.Request) (*http.Response, error)

func (fn roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) {
	return fn(request)
}

func TestAgentRunEventsReconnectsFromLastEventID(t *testing.T) {
	var requests atomic.Int32
	client := New("http://example.test", "token")
	client.HTTPClient.Transport = roundTripFunc(func(r *http.Request) (*http.Response, error) {
		var body string
		switch requests.Add(1) {
		case 1:
			if got := r.Header.Get("Last-Event-ID"); got != "" {
				t.Errorf("first Last-Event-ID = %q, want empty", got)
			}
			body = "id: 1\nevent: record\ndata: {\"type\":\"record\",\"record\":{\"turn_id\":\"turn_1\",\"data\":{\"type\":\"text\",\"text\":\"hello\"}}}\n\n"
		case 2:
			if got := r.Header.Get("Last-Event-ID"); got != "1" {
				t.Errorf("second Last-Event-ID = %q, want 1", got)
			}
			body = "id: 2\nevent: record\ndata: {\"type\":\"record\",\"record\":{\"turn_id\":\"turn_1\",\"data\":{\"type\":\"complete\",\"status\":\"completed\"}}}\n\n"
		default:
			t.Errorf("unexpected request %d", requests.Load())
		}
		return &http.Response{
			StatusCode: http.StatusOK,
			Header:     http.Header{"Content-Type": []string{"text/event-stream"}},
			Body:       io.NopCloser(strings.NewReader(body)),
			Request:    r,
		}, nil
	})

	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	events, err := client.AgentRunEvents(ctx, &AgentRun{
		ID:        "turn_1",
		SessionID: "ses_1",
	})
	if err != nil {
		t.Fatal(err)
	}

	var got []SSEEvent
	for event := range events {
		got = append(got, event)
	}
	if len(got) != 2 {
		t.Fatalf("got %d events, want 2", len(got))
	}
	if got[0].ID != "1" || got[0].Type != "text" {
		t.Fatalf("first event = %#v", got[0])
	}
	if got[1].ID != "2" || got[1].Type != "complete" {
		t.Fatalf("second event = %#v", got[1])
	}
}
