package runtime_test

import (
	"context"
	"path/filepath"
	"testing"
	"time"

	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/envelope"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/event"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/orchestrator"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/runtime"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/runtime/scripted"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/store"
	"github.com/flothus/tmux-xterm-research/server-go/internal/harness/transport"
)

// TestPhaseG_ConnectorForwardsAcrossSubOrgs is the Phase G done-criterion:
// a cross-suborg task is routed through a connector agent that calls
// forward_with_translation; both target sub-orgs receive the work as a
// regular delegate.
func TestPhaseG_ConnectorForwardsAcrossSubOrgs(t *testing.T) {
	tmp := t.TempDir()
	st, err := store.Open(filepath.Join(tmp, "harness.db"))
	if err != nil {
		t.Fatal(err)
	}
	defer st.Close()
	bus := event.NewBus(st)
	q := transport.New(st, bus)
	orch := orchestrator.New(st, bus)
	rt := scripted.New()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	_ = orch.CreateRun(ctx, "run-g", "phase G")
	for _, id := range []string{"connector", "fe-lead", "be-lead"} {
		_, _ = st.DB().Exec(`INSERT INTO agents(id, run_id, status, spawned_at, heartbeat_at) VALUES(?,'run-g','running',?,?)`,
			id, store.FmtTime(store.Now()), store.FmtTime(store.Now()))
	}

	// Connector script: forwards the same intent to fe-lead and be-lead.
	rt.SetScript("connector", []*runtime.LLMResponse{
		{
			Text: "splitting cross-suborg work",
			Tokens: runtime.TokenUsage{Prompt: 200, Completion: 100},
			ToolCalls: []runtime.ToolCall{
				{Name: "forward_with_translation", Args: map[string]any{
					"to":               "fe-lead",
					"intent":           "render the tooltip",
					"task_id":          "task-g-1",
					"translation_note": "this is the visual half of the cross-cut request",
				}},
				{Name: "forward_with_translation", Args: map[string]any{
					"to":               "be-lead",
					"intent":           "emit the trace event",
					"task_id":          "task-g-2",
					"translation_note": "this is the BE half",
				}},
			},
		},
	})
	_, _ = rt.Spawn(ctx, runtime.SpawnSpec{
		AgentID: "connector", RunID: "run-g",
		Tools: []string{"forward_with_translation"},
	})
	connector := runtime.NewAgent(rt, st, bus, q, "connector", "connector", "run-g",
		nil, []string{"forward_with_translation"}, "scripted", 0.001)

	// Tasks for both sides.
	_ = orch.CreateTask(ctx, orchestrator.Task{ID: "task-g-1", RunID: "run-g", Title: "fe half"})
	_ = orch.CreateTask(ctx, orchestrator.Task{ID: "task-g-2", RunID: "run-g", Title: "be half"})

	// Master sends the cross-cut prompt to the connector.
	delegate := &envelope.Envelope{
		ID: "m-cross", RunID: "run-g",
		From: "master", To: "connector", Type: envelope.TypeDelegate,
		TaskID: "task-g-1", TTLMs: 60000,
		Payload: envelope.Payload{Intent: "add tooltip + trace event", Expects: envelope.ExpectsReport},
	}
	if err := q.Send(ctx, delegate); err != nil {
		t.Fatal(err)
	}
	if _, err := connector.HandleOne(ctx); err != nil {
		t.Fatal(err)
	}

	// Both leads receive forwarded delegates.
	feMsg, _ := q.Receive(ctx, "fe-lead")
	beMsg, _ := q.Receive(ctx, "be-lead")
	if feMsg == nil || feMsg.Type != envelope.TypeDelegate {
		t.Fatalf("fe-lead delegate missing or wrong type: %+v", feMsg)
	}
	if beMsg == nil || beMsg.Type != envelope.TypeDelegate {
		t.Fatalf("be-lead delegate missing or wrong type: %+v", beMsg)
	}
	if feMsg.Payload.Intent != "render the tooltip" {
		t.Errorf("fe intent = %q", feMsg.Payload.Intent)
	}
	if note, _ := feMsg.Payload.Extra["translation_note"].(string); note == "" {
		t.Errorf("translation_note missing on fe message")
	}
}
