package cli_test

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

	"go.uber.org/zap"

	clipkg "iop/apps/node/internal/adapters/cli"
	"iop/apps/node/internal/adapters/cli/internal/testutil"
	noderuntime "iop/apps/node/internal/runtime"
	"iop/packages/go/config"
)

func TestCLIExecutePersistentWaitsForSlowFirstOutput(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"slow-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 0.2; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 50,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-1",
		Target: "slow-echo",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	if events[len(events)-1].Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected last event to be complete, got %q", events[len(events)-1].Type)
	}
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistentProcessExitReturnsError(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"exit-on-input": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "before-exit\n"; exit 2; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	sink := &testutil.FakeSink{}
	err := c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:  "run-1",
		Target: "exit-on-input",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err == nil {
		t.Fatal("expected non-nil error when persistent process exits")
	}

	errStr := err.Error()
	t.Logf("Got error: %q", errStr)
	if !strings.Contains(errStr, "before-exit") {
		t.Errorf("expected error to contain recent output 'before-exit', got %q", errStr)
	}
	if !strings.Contains(errStr, "exit status 2") {
		t.Errorf("expected error to contain exit status 'exit status 2', got %q", errStr)
	}
	if !strings.Contains(errStr, "target=exit-on-input") {
		t.Errorf("expected error to contain target=exit-on-input, got %q", errStr)
	}

	events := sink.Events()
	var errorEvent noderuntime.RuntimeEvent
	var hasError bool
	for _, e := range events {
		if e.Type == noderuntime.EventTypeError {
			hasError = true
			errorEvent = e
		}
	}
	if !hasError {
		t.Fatal("expected error event in emitted events")
	}
	if !strings.Contains(errorEvent.Error, "before-exit") {
		t.Errorf("expected error event to contain recent output, got %q", errorEvent.Error)
	}
	if len(events) > 0 && events[len(events)-1].Type == noderuntime.EventTypeComplete {
		t.Fatal("last event should not be complete when process exits unexpectedly")
	}
}

func TestCLIStartPersistentTerminalAndExecuteWritesPrompt(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"echo-persistent": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 300,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	sink := &testutil.FakeSink{}
	err := c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:  "run-1",
		Target: "echo-persistent",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	var started, completed bool
	for _, e := range events {
		switch e.Type {
		case noderuntime.EventTypeStart:
			started = true
		case noderuntime.EventTypeComplete:
			completed = true
		}
	}
	if !started {
		t.Fatal("expected start event")
	}
	if !completed {
		t.Fatal("expected complete event")
	}
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistentTerminalSendsCarriageReturn(t *testing.T) {
	testutil.RequirePTYSupport(t)
	if _, err := osexec.LookPath("stty"); err != nil {
		t.Skip("stty required")
	}

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"raw-tui": {
				Command:               os.Args[0],
				Args:                  []string{"-test.run=TestRawTUIHelperProcess", "--"},
				Env:                   []string{"IOP_RAW_TUI_HELPER=1"},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-raw-tui",
		Target: "raw-tui",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
	if last := events[len(events)-1]; last.Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected complete event, got %s", last.Type)
	}
}

func TestCLIExecutePersistentTerminalAcceptsClaudeBypassWarning(t *testing.T) {
	testutil.RequirePTYSupport(t)
	if _, err := osexec.LookPath("stty"); err != nil {
		t.Skip("stty required")
	}

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-warning": {
				Command:               os.Args[0],
				Args:                  []string{"-test.run=TestRawTUIHelperProcess", "--"},
				Env:                   []string{"IOP_CLAUDE_WARNING_HELPER=1"},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-claude-warning",
		Target: "claude-warning",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	if combined := testutil.CollectDeltas(sink.Events()); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistentTerminalAcceptsClaudeWorkspaceTrustAndBypassWarning(t *testing.T) {
	testutil.RequirePTYSupport(t)
	if _, err := osexec.LookPath("stty"); err != nil {
		t.Skip("stty required")
	}

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-trust-warning": {
				Command:               os.Args[0],
				Args:                  []string{"-test.run=TestRawTUIHelperProcess", "--"},
				Env:                   []string{"IOP_CLAUDE_TRUST_WARNING_HELPER=1"},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-claude-trust-warning",
		Target: "claude-trust-warning",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	if combined := testutil.CollectDeltas(sink.Events()); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistentClaudeTUICancelsSessionLimitUpgradePrompt(t *testing.T) {
	testutil.RequirePTYSupport(t)
	if _, err := osexec.LookPath("stty"); err != nil {
		t.Skip("stty required")
	}

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               os.Args[0],
				Args:                  []string{"-test.run=TestRawTUIHelperProcess", "--"},
				Env:                   []string{"IOP_CLAUDE_RATE_LIMIT_HELPER=1"},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-claude-rate-limit",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if !errors.Is(err, noderuntime.ErrRunCancelled) {
		t.Fatalf("expected run cancelled, got %v", err)
	}
	var cancelMsg string
	for _, ev := range sink.Events() {
		if ev.Type == noderuntime.EventTypeCancelled {
			cancelMsg = ev.Message
		}
		if ev.Type == noderuntime.EventTypeError {
			t.Fatalf("expected cancellation, got error event %q", ev.Error)
		}
	}
	if !strings.Contains(cancelMsg, "session limit") {
		t.Fatalf("expected cancelled event to mention session limit, got %q", cancelMsg)
	}
}

func TestCLIExecutePersistentClaudeTUIReplaysPromptAfterStartupReadyRace(t *testing.T) {
	testutil.RequirePTYSupport(t)
	if _, err := osexec.LookPath("stty"); err != nil {
		t.Skip("stty required")
	}

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               os.Args[0],
				Args:                  []string{"-test.run=TestRawTUIHelperProcess", "--"},
				Env:                   []string{"IOP_CLAUDE_READY_REPLAY_HELPER=1"},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  40,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-claude-ready-race",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}
	if combined := testutil.CollectDeltas(sink.Events()); combined != "replay:hello" {
		t.Fatalf("expected replayed prompt response, got %q", combined)
	}
}

func TestRawTUIHelperProcess(t *testing.T) {
	switch {
	case os.Getenv("IOP_RAW_TUI_HELPER") == "1":
		runRawTUIHelper()
	case os.Getenv("IOP_CLAUDE_WARNING_HELPER") == "1":
		runClaudeWarningHelper()
	case os.Getenv("IOP_CLAUDE_TRUST_WARNING_HELPER") == "1":
		runClaudeTrustAndWarningHelper()
	case os.Getenv("IOP_CLAUDE_RATE_LIMIT_HELPER") == "1":
		runClaudeRateLimitHelper()
	case os.Getenv("IOP_CLAUDE_READY_REPLAY_HELPER") == "1":
		runClaudeReadyReplayHelper()
	default:
		return
	}
}

func setRawTerminal() {
	cmd := osexec.Command("stty", "raw", "-echo")
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "stty raw: %v\n", err)
		os.Exit(2)
	}
}

func runRawTUIHelper() {
	setRawTerminal()
	readPromptAndReply()
}

func runClaudeWarningHelper() {
	setRawTerminal()
	fmt.Fprint(os.Stdout, "WARNING: Claude Code running in BypassPermissions mode\r\n2. Yes, I accept\r\n")
	_ = os.Stdout.Sync()

	want := []byte{'\x1b', '[', 'B', '\r'}
	seen := make([]byte, 0, len(want))
	buf := make([]byte, 1)
	for {
		n, err := os.Stdin.Read(buf)
		if n > 0 {
			seen = append(seen, buf[0])
			if len(seen) > len(want) {
				seen = seen[len(seen)-len(want):]
			}
			if string(seen) == string(want) {
				fmt.Fprint(os.Stdout, "ready\r\n")
				_ = os.Stdout.Sync()
				break
			}
		}
		if err != nil {
			os.Exit(0)
		}
	}

	readPromptAndReply()
}

func runClaudeTrustAndWarningHelper() {
	setRawTerminal()
	fmt.Fprint(os.Stdout, "Quick safety check: Is this a project you created or one you trust?\r\n❯ 1. Yes, I trust this folder\r\n2. No, exit\r\n")
	_ = os.Stdout.Sync()

	buf := make([]byte, 1)
	for {
		n, err := os.Stdin.Read(buf)
		if n > 0 && buf[0] == '\r' {
			break
		}
		if err != nil {
			os.Exit(0)
		}
	}

	fmt.Fprint(os.Stdout, "WARNING: Claude Code running in BypassPermissions mode\r\n2. Yes, I accept\r\n")
	_ = os.Stdout.Sync()

	want := []byte{'\x1b', '[', 'B', '\r'}
	seen := make([]byte, 0, len(want))
	for {
		n, err := os.Stdin.Read(buf)
		if n > 0 {
			seen = append(seen, buf[0])
			if len(seen) > len(want) {
				seen = seen[len(seen)-len(want):]
			}
			if string(seen) == string(want) {
				fmt.Fprint(os.Stdout, "ready\r\n")
				_ = os.Stdout.Sync()
				break
			}
		}
		if err != nil {
			os.Exit(0)
		}
	}

	readPromptAndReply()
}

func runClaudeRateLimitHelper() {
	setRawTerminal()
	for {
		buf := make([]byte, 1)
		n, err := os.Stdin.Read(buf)
		if n > 0 && buf[0] == '\r' {
			fmt.Fprint(os.Stdout, "\u25cf \u23bf  You've hit your session limit \u00b7 resets 12:50pm (Asia/Seoul)\r\n")
			fmt.Fprint(os.Stdout, "What do you want to do?\r\n❯ 1. Stop and wait for limit to reset\r\n2. Upgrade your plan\r\n")
			_ = os.Stdout.Sync()
		}
		if err != nil {
			os.Exit(0)
		}
	}
}

func runClaudeReadyReplayHelper() {
	setRawTerminal()
	fmt.Fprint(os.Stdout, "Quick safety check: Is this a project you created or one you trust?\r\n❯ 1. Yes, I trust this folder\r\n2. No, exit\r\n")
	_ = os.Stdout.Sync()

	_ = readRawLine()
	time.Sleep(150 * time.Millisecond)
	_ = readRawLine()

	fmt.Fprint(os.Stdout, "\r\n❯ ")
	_ = os.Stdout.Sync()

	prompt := readRawLine()
	fmt.Fprintf(os.Stdout, "\r\n\u25cf replay:%s\r\n\u276f ", prompt)
	_ = os.Stdout.Sync()

	buf := make([]byte, 1)
	for {
		if _, err := os.Stdin.Read(buf); err != nil {
			os.Exit(0)
		}
	}
}

func readRawLine() string {
	var line []byte
	buf := make([]byte, 1)
	for {
		n, err := os.Stdin.Read(buf)
		if n > 0 {
			if buf[0] == '\r' || buf[0] == '\n' {
				return string(line)
			}
			line = append(line, buf[0])
		}
		if err != nil {
			os.Exit(0)
		}
	}
}

func readPromptAndReply() {
	var prompt []byte
	buf := make([]byte, 1)
	for {
		n, err := os.Stdin.Read(buf)
		if n > 0 {
			if buf[0] == '\r' {
				fmt.Fprintf(os.Stdout, "reply:%s\n", string(prompt))
				_ = os.Stdout.Sync()
				prompt = prompt[:0]
			} else {
				prompt = append(prompt, buf[0])
			}
		}
		if err != nil {
			os.Exit(0)
		}
	}
}

func TestCLIStartPersistentTerminalEmitsRawChunksWithoutNewline(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"raw-terminal": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "chunk:%s" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-raw",
		Target: "raw-terminal",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "chunk:hello") {
		t.Fatalf("expected raw chunk in deltas, got %q", combined)
	}
	if last := events[len(events)-1]; last.Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected complete event, got %s", last.Type)
	}
}

func TestCLIStartPersistentTerminalUsesWidePTY(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"size-terminal": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do stty size; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-size",
		Target: "size-terminal",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	if combined := testutil.CollectDeltas(sink.Events()); !strings.Contains(combined, "720 1024") {
		t.Fatalf("expected wide PTY size in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistentClaudeTUIFiltersTerminalChrome(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf '\033[2C\r\033[7A\342\227\217\033[1Cmessage:%s\r\n\302\267 Cogitating... (1s, 1 tokens)\r\n\342\235\257 ' "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-filter",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	combined := testutil.CollectDeltas(events)
	if combined != "message:hello" {
		t.Fatalf("expected only assistant message delta, got %q", combined)
	}
	if last := events[len(events)-1]; last.Type != noderuntime.EventTypeComplete || last.Message != "prompt-ready" {
		t.Fatalf("expected prompt-ready completion, got type=%q message=%q", last.Type, last.Message)
	}
}

func TestCLIExecutePersistentClaudeTUIStreamsLineBeforeIdle(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf 'sud fragment\r\n\342\234\242 Dilly-dallying\342\200\246\r\n* Dilly-dallying\342\200\246\r\n'; sleep 0.05; printf '\342\227\217 sudo runs commands\r\n\342\235\257 '; sleep 0.15; printf '\r\033[2A\033[2K\342\227\217 sudo runs commands with elevated privileges.\r\n\342\235\257 '; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 300,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-growing",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "explain sudo"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	combined := testutil.CollectDeltas(events)
	if combined != "sudo runs commands with elevated privileges." {
		t.Fatalf("expected full growing message, got %q", combined)
	}
	if last := events[len(events)-1]; last.Type != noderuntime.EventTypeComplete || last.Message != "prompt-ready" {
		t.Fatalf("expected prompt-ready completion, got type=%q message=%q", last.Type, last.Message)
	}
}

func TestCLIExecutePersistentClaudeTUIWaitsForPromptReadyAfterPartialOutput(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf '\342\227\217 first chunk\r\n\342\234\242 Dilly-dallying\342\200\246\r\n'; sleep 0.15; printf 'second chunk\r\n\342\235\257 '; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 60,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-delayed-tail",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "write two chunks"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	combined := testutil.CollectDeltas(events)
	if !strings.Contains(combined, "first chunk") ||
		!strings.Contains(combined, "second chunk") ||
		strings.Index(combined, "first chunk") > strings.Index(combined, "second chunk") {
		t.Fatalf("expected full delayed message, got %q", combined)
	}
	if last := events[len(events)-1]; last.Type != noderuntime.EventTypeComplete || last.Message != "prompt-ready" {
		t.Fatalf("expected prompt-ready completion, got type=%q message=%q", last.Type, last.Message)
	}
}

func TestCLIExecutePersistentClaudeTUIDoesNotCompleteOnStatusOnlyIdle(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"claude-tui": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf '3\r\n\r\nThundering\342\200\2466\r\n'; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 60,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	runCtx, cancel := context.WithTimeout(ctx, 220*time.Millisecond)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(runCtx, noderuntime.ExecutionSpec{
		RunID:  "run-status-only",
		Target: "claude-tui",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err == nil {
		t.Fatal("execute completed successfully before any assistant message")
	}

	for _, event := range sink.Events() {
		if event.Type == noderuntime.EventTypeDelta {
			t.Fatalf("status-only output should not be emitted as delta: %q", event.Delta)
		}
		if event.Type == noderuntime.EventTypeComplete {
			t.Fatalf("status-only output should not emit complete: %+v", event)
		}
	}
}

// TestCLIExecutePersistentCancelDoesNotTerminateSession verifies that a
// cancelled run leaves the session alive so subsequent runs can reuse it.
func TestCLIExecutePersistentCancelDoesNotTerminateSession(t *testing.T) {
	testutil.RequirePTYSupport(t)

	// ResponseIdleTimeoutMS is short so the cancel-drain exits quickly,
	// allowing the second execute to acquire the session lock promptly.
	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"slow-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 0.05; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 150,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	// First execute: cancel before idle timeout fires.
	firstCtx, firstCancel := context.WithTimeout(ctx, 100*time.Millisecond)
	defer firstCancel()

	sink1 := &testutil.FakeSink{}
	_ = c.Execute(firstCtx, noderuntime.ExecutionSpec{
		RunID:  "run-1",
		Target: "slow-echo",
		Input:  map[string]any{"prompt": "first"},
	}, sink1)

	// Give time for cancel drain to finish (drain uses idleTimeout=150ms).
	time.Sleep(400 * time.Millisecond)

	// Second execute on same session — must succeed (session still alive).
	execCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
	defer cancel()

	sink2 := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-2",
		Target: "slow-echo",
		Input:  map[string]any{"prompt": "second"},
	}, sink2)
	if err != nil {
		t.Fatalf("second execute after cancel must succeed (session should be alive): %v", err)
	}
	events2 := sink2.Events()
	if len(events2) == 0 || events2[len(events2)-1].Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected complete event on second run, got %v", events2)
	}
}

func TestCLIExecutePersistentConsecutiveExecutes(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"consecutive-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 100,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	sink1 := &testutil.FakeSink{}
	err := c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:  "run-1",
		Target: "consecutive-echo",
		Input:  map[string]any{"prompt": "first"},
	}, sink1)
	if err != nil {
		t.Fatalf("first execute: %v", err)
	}
	events1 := sink1.Events()
	if events1[len(events1)-1].Type != noderuntime.EventTypeComplete {
		t.Fatalf("first run: expected last event to be complete, got %q", events1[len(events1)-1].Type)
	}

	sink2 := &testutil.FakeSink{}
	err = c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:  "run-2",
		Target: "consecutive-echo",
		Input:  map[string]any{"prompt": "second"},
	}, sink2)
	if err != nil {
		t.Fatalf("second execute: %v", err)
	}
	events2 := sink2.Events()
	if events2[len(events2)-1].Type != noderuntime.EventTypeComplete {
		t.Fatalf("second run: expected last event to be complete, got %q", events2[len(events2)-1].Type)
	}

	for _, e := range events2 {
		if e.Type == noderuntime.EventTypeDelta && strings.Contains(e.Delta, "first") {
			t.Fatalf("second run received first run's delta (session contamination): %q", e.Delta)
		}
	}
}

func TestCLIExecutePersistentCreatesIndependentSessionsForSameProfile(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"multi-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 200,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())
	ctx := context.Background()

	sinkA := &testutil.FakeSink{}
	err := c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:     "run-a",
		Target:    "multi-echo",
		SessionID: "session-a",
		Input:     map[string]any{"prompt": "alpha"},
	}, sinkA)
	if err != nil {
		t.Fatalf("session-a execute: %v", err)
	}

	sinkB := &testutil.FakeSink{}
	err = c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:     "run-b",
		Target:    "multi-echo",
		SessionID: "session-b",
		Input:     map[string]any{"prompt": "beta"},
	}, sinkB)
	if err != nil {
		t.Fatalf("session-b execute: %v", err)
	}

	if combined := testutil.CollectDeltas(sinkA.Events()); !strings.Contains(combined, "alpha") {
		t.Fatalf("session-a: expected alpha in deltas, got %q", combined)
	}
	if combined := testutil.CollectDeltas(sinkB.Events()); !strings.Contains(combined, "beta") {
		t.Fatalf("session-b: expected beta in deltas, got %q", combined)
	}
	if combined := testutil.CollectDeltas(sinkA.Events()); strings.Contains(combined, "beta") {
		t.Fatalf("session-a contaminated with session-b output: %q", combined)
	}
}

func TestCLIExecutePersistentRequireExistingSessionFailsWhenMissing(t *testing.T) {
	testutil.RequireUnixShell(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"echo-req": {
				Command:               "sh",
				Args:                  []string{"-c", `while IFS= read -r line; do printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              false,
				ResponseIdleTimeoutMS: 200,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())
	ctx := context.Background()

	sink := &testutil.FakeSink{}
	err := c.Execute(ctx, noderuntime.ExecutionSpec{
		RunID:       "run-1",
		Target:      "echo-req",
		SessionID:   "nonexistent",
		SessionMode: noderuntime.SessionModeRequireExisting,
		Input:       map[string]any{"prompt": "hello"},
	}, sink)
	if err == nil {
		t.Fatal("expected error for require-existing with missing session")
	}
	if strings.Contains(err.Error(), "start") {
		t.Fatalf("should not have started a new process, got: %v", err)
	}
}

func TestCLIExecutePersistent_UserCancelEmitsUserCancelMessage(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"slow-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 10; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithCancel(ctx)

	sink := &testutil.FakeSink{}
	go func() {
		time.Sleep(100 * time.Millisecond)
		cancel()
	}()

	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-usercancel",
		Target: "slow-echo",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err == nil {
		t.Fatalf("expected error, got nil")
	}

	events := sink.Events()
	var lastMsg string
	var cancelEvent bool
	for i := len(events) - 1; i >= 0; i-- {
		if events[i].Type == noderuntime.EventTypeCancelled {
			cancelEvent = true
			lastMsg = events[i].Message
		}
	}
	if !cancelEvent {
		t.Fatal("expected cancelled event")
	}
	if lastMsg != "user-cancel" {
		t.Fatalf("expected cancel Message 'user-cancel', got %q", lastMsg)
	}
}

func TestCLIExecutePersistent_TimeoutEmitsTimeoutMessage(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"slow-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 10; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
	defer cancel()

	sink := &testutil.FakeSink{}
	executeErr := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-timeout",
		Target: "slow-echo",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if executeErr == nil {
		t.Fatalf("expected error, got nil")
	}

	events := sink.Events()
	var lastMsg string
	var cancelEvent bool
	for i := len(events) - 1; i >= 0; i-- {
		if events[i].Type == noderuntime.EventTypeCancelled {
			cancelEvent = true
			lastMsg = events[i].Message
		}
	}
	if !cancelEvent {
		t.Fatal("expected cancelled event")
	}
	if lastMsg != "timeout" {
		t.Fatalf("expected cancel Message 'timeout', got %q", lastMsg)
	}
}

func TestCLIExecutePersistent_CompletionMarkerLineEndsRun(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"marker-line": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "reply:%s\n" "$line"; printf "<<END_OF_RESPONSE>>\n"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
				CompletionMarker:      config.CompletionMarkerConf{Line: "<<END_OF_RESPONSE>>"},
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-marker-line",
		Target: "marker-line",
		Input:  map[string]any{"prompt": "hello"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	last := events[len(events)-1]
	if last.Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected last event to be complete, got %q", last.Type)
	}
	if last.Message != "completion-marker" {
		t.Fatalf("expected Message 'completion-marker', got %q", last.Message)
	}
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hello") {
		t.Fatalf("expected reply:hello in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistent_CompletionMarkerRegexEndsRun(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"marker-regex": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do printf "reply:%s\n" "$line"; printf "DONE 42\n"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 500,
				StartupIdleTimeoutMS:  50,
				CompletionMarker:      config.CompletionMarkerConf{Regex: "^DONE \\d+$"},
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-marker-regex",
		Target: "marker-regex",
		Input:  map[string]any{"prompt": "hi"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	last := events[len(events)-1]
	if last.Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected last event to be complete, got %q", last.Type)
	}
	if last.Message != "completion-marker" {
		t.Fatalf("expected Message 'completion-marker', got %q", last.Message)
	}
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:hi") {
		t.Fatalf("expected reply:hi in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistent_NoMarkerFallsBackToIdleTimeout(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"no-marker": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 0.1; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 50,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-no-marker",
		Target: "no-marker",
		Input:  map[string]any{"prompt": "fallback"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	last := events[len(events)-1]
	if last.Type != noderuntime.EventTypeComplete {
		t.Fatalf("expected last event to be complete, got %q", last.Type)
	}
	if last.Message != "idle-timeout" {
		t.Fatalf("expected Message 'idle-timeout' when no marker is set, got %q", last.Message)
	}
	if combined := testutil.CollectDeltas(events); !strings.Contains(combined, "reply:fallback") {
		t.Fatalf("expected reply:fallback in deltas, got %q", combined)
	}
}

func TestCLIExecutePersistent_IdleTimeoutMessageReason(t *testing.T) {
	testutil.RequirePTYSupport(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"idle-reason": {
				Command:               "sh",
				Args:                  []string{"-c", `stty -echo; while IFS= read -r line; do sleep 0.1; printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              true,
				ResponseIdleTimeoutMS: 50,
				StartupIdleTimeoutMS:  50,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())

	ctx := context.Background()
	if err := c.Start(ctx); err != nil {
		t.Fatalf("start: %v", err)
	}
	defer func() { _ = c.Stop(ctx) }()

	execCtx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()

	sink := &testutil.FakeSink{}
	err := c.Execute(execCtx, noderuntime.ExecutionSpec{
		RunID:  "run-idle-reason",
		Target: "idle-reason",
		Input:  map[string]any{"prompt": "test"},
	}, sink)
	if err != nil {
		t.Fatalf("execute: %v", err)
	}

	events := sink.Events()
	var complete *noderuntime.RuntimeEvent
	for i := range events {
		if events[i].Type == noderuntime.EventTypeComplete {
			complete = &events[i]
		}
	}
	if complete == nil {
		t.Fatal("expected complete event")
	}
	if complete.Message != "idle-timeout" {
		t.Fatalf("expected Message 'idle-timeout', got %q", complete.Message)
	}
}

func TestCLIExecutePersistentMaintainsHundredLogicalSessions(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping heavy session test in short mode")
	}
	testutil.RequireUnixShell(t)

	cfg := config.CLIConf{
		Enabled: true,
		Profiles: map[string]config.CLIProfileConf{
			"hundred-echo": {
				Command:               "sh",
				Args:                  []string{"-c", `while IFS= read -r line; do printf "reply:%s\n" "$line"; done`},
				Persistent:            true,
				Terminal:              false,
				ResponseIdleTimeoutMS: 300,
			},
		},
	}
	c := clipkg.New(cfg, zap.NewNop())
	ctx := context.Background()

	const n = 20
	for i := 0; i < n; i++ {
		sessionID := "session-" + string(rune('a'+i%26)) + "-" + string(rune('0'+i/26))
		sink := &testutil.FakeSink{}
		err := c.Execute(ctx, noderuntime.ExecutionSpec{
			RunID:     "run-first-" + sessionID,
			Target:    "hundred-echo",
			SessionID: sessionID,
			Input:     map[string]any{"prompt": "ping-" + sessionID},
		}, sink)
		if err != nil {
			t.Fatalf("session %q first execute: %v", sessionID, err)
		}
	}

	// Second round — all sessions must still be alive.
	for i := 0; i < n; i++ {
		sessionID := "session-" + string(rune('a'+i%26)) + "-" + string(rune('0'+i/26))
		sink := &testutil.FakeSink{}
		err := c.Execute(ctx, noderuntime.ExecutionSpec{
			RunID:     "run-second-" + sessionID,
			Target:    "hundred-echo",
			SessionID: sessionID,
			Input:     map[string]any{"prompt": "pong-" + sessionID},
		}, sink)
		if err != nil {
			t.Fatalf("session %q second execute: %v", sessionID, err)
		}
	}

	_ = c.Stop(ctx)
}
