package dispatcher

import (
	"context"
	"io"
	"strings"
	"testing"

	"github.com/tidbcloud/AgentTeam/desktop/internal/agent"
	"github.com/tidbcloud/AgentTeam/desktop/internal/agent/drivercontract"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

// fixtureDriver spawns a no-op runtime whose Wait blocks on context cancel.
type fixtureDriver struct{}

func (fixtureDriver) Name() string { return "claude" }

func (fixtureDriver) SupportsStdinNotification() bool { return true }

func (fixtureDriver) MCPToolPrefix() string { return "mcp__agentteam__" }

func (fixtureDriver) Spawn(ctx context.Context, cfg drivercontract.LaunchConfig) (drivercontract.SpawnResult, error) {
	_, pipeW := io.Pipe()
	empty := io.NopCloser(strings.NewReader(""))
	return drivercontract.SpawnResult{
		SessionID:  cfg.AgentID + "-session",
		Stdout:     empty,
		StderrTail: func() string { return "" },
		Stdin:      pipeW,
		Wait:       func() error { <-ctx.Done(); return nil },
		Terminate:  func() { _ = pipeW.Close() },
		Cleanup:    func() {},
	}, nil
}

func (fixtureDriver) ParseLine(string) []drivercontract.ParsedEvent { return nil }

func (fixtureDriver) EncodeStdinMessage(text, _ string) []byte { return []byte(text) }

// NewDispatcherScopeFixture builds a live Process through the real
// agent.NewProcess with a seeded initial delivery — no production seam.
func NewDispatcherScopeFixture(t *testing.T) *agent.Process {
	t.Helper()
	process, err := agent.NewProcess(
		context.Background(),
		fixtureDriver{},
		drivercontract.LaunchConfig{AgentID: "agent-fixture", WorkDir: t.TempDir()},
		agent.ProcessOptions{
			InitialDelivery: &types.InboxMessage{MessageID: "m1", Target: "#fixture-turn"},
		},
	)
	if err != nil {
		t.Fatalf("fixture process: %v", err)
	}
	t.Cleanup(func() { process.Stop() })
	return process
}

// InteractiveSessionFixture builds a session carrying the given MCP token and
// process for dispatcher-level route tests.
func InteractiveSessionFixture(agentID string, mcpToken string, process *agent.Process) *interactiveSession {
	return &interactiveSession{
		sessionKey:    agentID,
		agentID:       agentID,
		serverAgentID: "server-agent-fixture",
		workDir:       "/tmp",
		mcpToken:      mcpToken,
		process:       process,
	}
}
