package orchestrator

import (
	"context"
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/workflow/plan"
	runkernel "github.com/tidbcloud/AgentTeam/internal/workflow/run"
	"github.com/tidbcloud/AgentTeam/internal/workflow/runartifact"
)

type artifactContentEffectRepository struct {
	effectRepositoryStub
	content []byte
}

func (repository *artifactContentEffectRepository) ResolveArtifactContent(_ context.Context, ref runartifact.Ref) ([]byte, error) {
	if ref.ArtifactID == "" {
		return nil, runartifact.ErrUnauthorizedReference
	}
	return append([]byte(nil), repository.content...), nil
}

func TestOversizedMessageContentUsesBoundArtifactReference(t *testing.T) {
	draft, err := runartifact.NewDraftForKind(runartifact.KindJoinAggregate, "wsp_1", "wri_1", "send", "act_send", []byte(`"large content"`))
	require.NoError(t, err)
	request := EffectRequest{
		Intent: runkernel.Intent{Kind: runkernel.IntentSendMessage, ActivationID: "act_send", NodeID: "send", TextRef: &draft.Ref, Retry: plan.ArtifactRetryPolicy{MaxAttempts: 1, BackoffNanos: 1}},
		Message: &MessageRequest{
			WorkspaceID: "wsp_1", PlanID: "pln_1", PlanVersionID: "plv_1", RunID: "wri_1", ActivationID: "act_send", EffectID: "wfx_1", NodeID: "send", SourceKind: "manual", OwnerUserID: "usr_1", AuthorMemberID: "mem_1", TargetRef: "#ops", ContentRef: &draft.Ref, ClientMessageID: "workflow-run:wfx_1",
		},
	}
	payload, err := EncodeEffectRequest(request)
	require.NoError(t, err)
	require.Less(t, len(payload), 4096)
	decoded, err := DecodeEffectRequest(payload)
	require.NoError(t, err)
	repository := &artifactContentEffectRepository{content: []byte(`"large content"`)}
	dispatcher := &EffectDispatcher{repository: repository}
	require.NoError(t, dispatcher.materializeMessageContent(context.Background(), decoded.Message))
	require.Equal(t, "large content", decoded.Message.Content)
	require.Nil(t, decoded.Message.ContentRef)

	var wire map[string]any
	require.NoError(t, json.Unmarshal(payload, &wire))
	require.NotNil(t, wire["message"].(map[string]any)["contentRef"])
}
