package iflow

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"

	"github.com/chenhg5/cc-connect/core"
)

func TestIFlowSessionIntegration(t *testing.T) {
	if os.Getenv("IFLOW_INTEGRATION") == "" {
		t.Skip("set IFLOW_INTEGRATION=1 to run")
	}
	if _, err := exec.LookPath("iflow"); err != nil {
		t.Skip("iflow CLI not found in PATH")
	}

	a, err := New(map[string]any{"work_dir": "/tmp"})
	if err != nil {
		t.Fatalf("New: %v", err)
	}

	sess, err := a.StartSession(context.Background(), "")
	if err != nil {
		t.Fatalf("StartSession: %v", err)
	}
	defer sess.Close()

	if err := sess.Send("Reply exactly READY", nil, nil); err != nil {
		t.Fatalf("Send #1: %v", err)
	}
	res1 := waitForResult(t, sess.Events())
	if !strings.Contains(strings.ToUpper(res1.Content), "READY") {
		t.Fatalf("unexpected first result: %q", res1.Content)
	}
	sid := sess.CurrentSessionID()
	if sid == "" {
		t.Fatal("expected session id after first send")
	}

	if err := sess.Send("Reply exactly RESUMED", nil, nil); err != nil {
		t.Fatalf("Send #2: %v", err)
	}
	res2 := waitForResult(t, sess.Events())
	if !strings.Contains(strings.ToUpper(res2.Content), "RESUMED") {
		t.Fatalf("unexpected second result: %q", res2.Content)
	}
	if sid2 := sess.CurrentSessionID(); sid2 != sid {
		t.Fatalf("session id changed: %q -> %q", sid, sid2)
	}

	resumed, err := a.StartSession(context.Background(), sid)
	if err != nil {
		t.Fatalf("StartSession resume: %v", err)
	}
	defer resumed.Close()
	if err := resumed.Send("Reply exactly CONTINUED", nil, nil); err != nil {
		t.Fatalf("Send resume: %v", err)
	}
	res3 := waitForResult(t, resumed.Events())
	if !strings.Contains(strings.ToUpper(res3.Content), "CONTINUED") {
		t.Fatalf("unexpected resumed result: %q", res3.Content)
	}
	if sid3 := resumed.CurrentSessionID(); sid3 != sid {
		t.Fatalf("resumed session id mismatch: want %q, got %q", sid, sid3)
	}
}

func waitForResult(t *testing.T, ch <-chan core.Event) core.Event {
	t.Helper()
	timeout := time.After(90 * time.Second)
	for {
		select {
		case ev, ok := <-ch:
			if !ok {
				t.Fatal("events channel closed")
			}
			switch ev.Type {
			case core.EventError:
				t.Fatalf("event error: %v", ev.Error)
			case core.EventResult:
				fmt.Printf("[RESULT] sid=%s content=%s\n", ev.SessionID, ev.Content)
				return ev
			}
		case <-timeout:
			t.Fatal("timeout waiting for result")
		}
	}
}
