package run

import (
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/core/domain"
	"github.com/tidbcloud/AgentTeam/internal/workflow/plan"
)

func TestRenderedMalformedMessageTargetRoutesFailureWithoutEffect(t *testing.T) {
	t.Parallel()

	kernel := compilePlanKernel(t, implicitFailureRuntimePlan)
	state, err := kernel.Start(Values{"target": "#tsk_Bad"})
	require.NoError(t, err)

	routed, err := kernel.Step(state, reducerNow)
	require.NoError(t, err)
	require.Empty(t, routed.Intents)
	require.Equal(t, StatusRunning, routed.State.Status)
	require.Len(t, routed.State.Activations, 2)

	source := routed.State.Activations[0]
	require.Equal(t, []string{"failed"}, source.SelectedPorts)
	require.NotNil(t, source.Failure)
	require.Equal(t, "message.target_invalid", source.Failure.Code)
	require.NotEmpty(t, source.Failure.Message)
}

func TestMessageScopeDestinationProducesNormalizedIntent(t *testing.T) {
	t.Parallel()

	kernel, graph := goldenKernel(t, "send_message_sent.json")
	node, ok := graph.Node("action")
	require.True(t, ok)
	scopeLiteral, err := json.Marshal(map[string]any{
		"kind":    "task",
		"scopeId": "tsk_abcdefghijklmn",
	})
	require.NoError(t, err)
	node.Config.SendMessage.Target = nil
	node.Config.SendMessage.Scope = &plan.ArtifactExpression{
		Op:         plan.ArtifactOpConst,
		ResultType: plan.TypeScope,
		Value:      scopeLiteral,
	}

	state, err := kernel.Start(Values{})
	require.NoError(t, err)
	transition, err := kernel.Step(state, reducerNow)
	require.NoError(t, err)
	require.Len(t, transition.Intents, 1)
	require.Empty(t, transition.Intents[0].Target)
	require.Equal(t, &domain.MessageScopeValue{
		Kind:    domain.MessageScopeKindTask,
		ScopeID: "tsk_abcdefghijklmn",
	}, transition.Intents[0].Scope)
}

func TestMalformedMessageScopeRoutesFailureWithoutEffect(t *testing.T) {
	t.Parallel()

	kernel, graph := goldenKernel(t, "send_message_sent.json")
	node, ok := graph.Node("action")
	require.True(t, ok)
	scopeLiteral, err := json.Marshal(map[string]any{
		"kind":    "team",
		"scopeId": "tsk_abcdefghijklmn",
	})
	require.NoError(t, err)
	node.Config.SendMessage.Target = nil
	node.Config.SendMessage.Scope = &plan.ArtifactExpression{
		Op:         plan.ArtifactOpConst,
		ResultType: plan.TypeScope,
		Value:      scopeLiteral,
	}

	state, err := kernel.Start(Values{})
	require.NoError(t, err)
	routed, err := kernel.Step(state, reducerNow)
	require.NoError(t, err)
	require.Empty(t, routed.Intents)
	require.Equal(t, "message.scope_invalid", routed.State.Activations[0].Failure.Code)
	require.Equal(t, []string{"failed"}, routed.State.Activations[0].SelectedPorts)
}

func TestStartThreadMessageIntentCarriesCompilerOwnedFlag(t *testing.T) {
	t.Parallel()

	kernel, graph := goldenKernel(t, "send_message_sent.json")
	node, ok := graph.Node("action")
	require.True(t, ok)
	node.Config.SendMessage.StartThread = true

	state, err := kernel.Start(Values{})
	require.NoError(t, err)
	transition, err := kernel.Step(state, reducerNow)
	require.NoError(t, err)
	require.Len(t, transition.Intents, 1)
	require.True(t, transition.Intents[0].StartThread)
}
