package converter

import (
	"encoding/json"
	"strings"
	"testing"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/core/domain"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
	"github.com/tidbcloud/AgentTeam/internal/store/taskboard"
)

func TestToMessagePresentationFailsClosedForInvalidEnvelope(t *testing.T) {
	invalid := &domain.MessagePresentation{Version: 1, Key: domain.MessagePresentationKeyWorkflowRecovery, Args: json.RawMessage(`{"runId":"wri_1"}`)}
	if got := ToMessagePresentation(invalid); got != nil {
		t.Fatalf("ToMessagePresentation(invalid) = %#v, want nil", got)
	}
	valid := domain.NewWorkflowRecoveryPresentation("wri_1", "wfx_1", "wfx_1", 1, 2)
	if got := ToMessagePresentation(valid); got == nil || got == valid || got.Key != valid.Key {
		t.Fatalf("ToMessagePresentation(valid) = %#v, want independent validated copy", got)
	}
}

func TestTaskConvertersPreserveListEmptySemantics(t *testing.T) {
	if got := ToTasks(nil); got != nil {
		t.Fatalf("ToTasks(nil) = %#v, want nil", got)
	}
	if got := ToTasks([]taskboard.Task{}); got != nil {
		t.Fatalf("ToTasks(empty) = %#v, want nil", got)
	}
	if got := ToTasksEmpty(nil); got == nil || len(got) != 0 {
		t.Fatalf("ToTasksEmpty(nil) = %#v, want non-nil empty slice", got)
	}
	if got := ToTasksEmpty([]taskboard.Task{}); got == nil || len(got) != 0 {
		t.Fatalf("ToTasksEmpty(empty) = %#v, want non-nil empty slice", got)
	}
}

func TestTaskChecklistConvertersPreserveNilVsEmpty(t *testing.T) {
	if got := FromTaskChecklistItems(nil); got != nil {
		t.Fatalf("FromTaskChecklistItems(nil) = %#v, want nil", got)
	}
	if got := FromTaskChecklistItems([]dto.TaskChecklistItem{}); got == nil || len(got) != 0 {
		t.Fatalf("FromTaskChecklistItems(empty) = %#v, want non-nil empty slice", got)
	}
	if got := ToTaskChecklistItems(nil); got != nil {
		t.Fatalf("ToTaskChecklistItems(nil) = %#v, want nil", got)
	}
	if got := ToTaskChecklistItems([]taskboard.TaskChecklistItem{}); got != nil {
		t.Fatalf("ToTaskChecklistItems(empty) = %#v, want nil", got)
	}
}

func TestTaskDaemonListConvertersPreserveEmptySliceBehavior(t *testing.T) {
	if got := ToTaskViews(nil); got == nil || len(got) != 0 {
		t.Fatalf("ToTaskViews(nil) = %#v, want non-nil empty slice", got)
	}
	if got := ToCreatedTaskSummaries(nil, nil); got == nil || len(got) != 0 {
		t.Fatalf("ToCreatedTaskSummaries(nil, nil) = %#v, want non-nil empty slice", got)
	}
	if got := ToClaimResults(nil); got == nil || len(got) != 0 {
		t.Fatalf("ToClaimResults(nil) = %#v, want non-nil empty slice", got)
	}
}

func TestToCreatedTaskSummariesPreservesReusedAndResolvedAssignee(t *testing.T) {
	assignee := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeAgent,
		PrincipalID: "agt_assignee",
		MemberID:    "mem_assignee",
		DisplayName: "Resolved Assignee",
	}
	got := ToCreatedTaskSummaries(
		[]taskboard.CreatedTask{
			{TaskScopeID: "scp_reused", TaskNumber: 8, Title: "reused", Reused: true},
			{TaskScopeID: "scp_created", TaskNumber: 9, Title: "created"},
		},
		[]taskboard.Task{
			{TaskScopeID: "scp_created", TaskNumber: 9, Status: "todo"},
			{TaskScopeID: "scp_reused", TaskNumber: 8, Status: "in_progress", AssigneeProfile: &assignee},
		},
	)

	if len(got) != 2 {
		t.Fatalf("ToCreatedTaskSummaries() length = %d, want 2", len(got))
	}
	if got[0].TaskNumber != 8 || !got[0].Reused || got[0].Status != "in_progress" {
		t.Fatalf("first created task = %#v, want reused input order and resolved status", got[0])
	}
	if got[0].AssigneeProfile == nil || got[0].AssigneeProfile.PrincipalID != "agt_assignee" || got[0].AssigneeProfile.MemberID != "mem_assignee" {
		t.Fatalf("first assigneeProfile = %#v, want resolved assignee", got[0].AssigneeProfile)
	}
	if got[1].TaskNumber != 9 || got[1].Reused || got[1].Status != "todo" || got[1].AssigneeProfile != nil {
		t.Fatalf("second created task = %#v, want unassigned new task", got[1])
	}
}

func TestTaskBrowseConvertersPreserveEmptyRows(t *testing.T) {
	got := ToTaskBrowseResponse(taskboard.TaskRowBrowsePage{})
	if got.Rows == nil || len(got.Rows) != 0 {
		t.Fatalf("ToTaskBrowseResponse empty rows = %#v, want non-nil empty slice", got.Rows)
	}
	column := ToTaskBoardColumnPage(taskboard.TaskBoardColumnPage{})
	if column.Tasks == nil || len(column.Tasks) != 0 {
		t.Fatalf("ToTaskBoardColumnPage empty tasks = %#v, want non-nil empty slice", column.Tasks)
	}
}

func TestTaskBrowseConvertersRoundTripStatusFilter(t *testing.T) {
	const want = "in_review"

	var request dto.TaskBrowseRequest
	if err := json.Unmarshal([]byte(`{"statusFilter":"in_review"}`), &request); err != nil {
		t.Fatalf("json.Unmarshal(TaskBrowseRequest) error = %v", err)
	}
	domain, err := FromTaskBrowseQuery(request)
	if err != nil {
		t.Fatalf("FromTaskBrowseQuery() error = %v", err)
	}
	if domain.StatusFilter != want {
		t.Fatalf("FromTaskBrowseQuery().StatusFilter = %q, want %q", domain.StatusFilter, want)
	}

	wire := ToTaskBrowseQuery(taskboard.TaskBrowseQuery{StatusFilter: want})
	if wire.StatusFilter != want {
		t.Fatalf("ToTaskBrowseQuery().StatusFilter = %q, want %q", wire.StatusFilter, want)
	}
	encoded, err := json.Marshal(wire)
	if err != nil {
		t.Fatalf("json.Marshal(ToTaskBrowseQuery()) error = %v", err)
	}
	if got := string(encoded); got != `{"statusFilter":"in_review"}` {
		t.Fatalf("json.Marshal(ToTaskBrowseQuery()) = %s, want statusFilter JSON field", got)
	}
}

func TestToTaskCarriesResolvedPrincipalProfiles(t *testing.T) {
	created := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeHuman,
		PrincipalID: "usr_resolved",
		MemberID:    "mem_creator",
		DisplayName: "Resolved Creator",
	}
	assignee := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeAgent,
		PrincipalID: "agt_resolved",
		MemberID:    "mem_agent",
		DisplayName: "Resolved Agent",
	}
	got := ToTask(taskboard.Task{
		ID:               "tsk_1",
		Title:            "profile task",
		Status:           "todo",
		CreatedByProfile: &created,
		CreatedByType:    "user",
		CreatedByID:      "usr_resolved",
		CreatedByName:    "Resolved Creator",
		AssigneeProfile:  &assignee,
	})
	if got.CreatedByProfile == nil || got.CreatedByProfile.PrincipalID != "usr_resolved" || got.CreatedByProfile.DisplayName != "Resolved Creator" {
		t.Fatalf("CreatedByProfile = %#v, want resolved creator profile", got.CreatedByProfile)
	}
	if got.AssigneeProfile == nil || got.AssigneeProfile.PrincipalID != "agt_resolved" || got.AssigneeProfile.DisplayName != "Resolved Agent" {
		t.Fatalf("AssigneeProfile = %#v, want resolved assignee profile", got.AssigneeProfile)
	}
	if got.CreatedByID != "usr_resolved" {
		t.Fatalf("CreatedByID = %q, want Resolved-derived creator compatibility id", got.CreatedByID)
	}
}

func TestToTaskDiscussionEntryCarriesMessageAuthorAndSource(t *testing.T) {
	editedAt := time.Date(2026, 6, 20, 16, 0, 0, 0, time.UTC)
	got := ToTaskDiscussionEntry(taskboard.TaskDiscussionEntry{
		ID:     "msg_1",
		TaskID: "tsk_1",
		Body:   "message-backed discussion",
		AuthorProfile: message.AuthorProfile{
			ActorType:   message.AuthorActorTypeAgent,
			PrincipalID: "agt_1",
			MemberID:    "mem_agent",
			TargetID:    "agent-one",
			DisplayName: "Agent One",
		},
		Source: message.ContributionSource{
			Kind:    message.ContributionSourceKindAgentRuntime,
			RefType: message.ContributionSourceRefTypeMessage,
			RefID:   "msg_1",
			Label:   "Agent One",
		},
		CreatedBy:           taskboard.TaskActor{Type: "agent", ID: "agt_1", Name: "Agent One"},
		EditedAt:            &editedAt,
		EditedByMemberID:    "mem_editor",
		EditRevision:        2,
		MessagePresentation: domain.NewWorkflowRecoveryPresentation("wri_1", "wfx_1", "wfx_1", 2, 5),
	})
	if got.AuthorProfile == nil {
		t.Fatalf("AuthorProfile = nil, want Resolved message author profile")
	}
	if got.AuthorProfile.ActorType != message.AuthorActorTypeAgent || got.AuthorProfile.DisplayName != "Agent One" {
		t.Fatalf("AuthorProfile = %#v, want agent display profile", got.AuthorProfile)
	}
	if got.Source == nil {
		t.Fatalf("Source = nil, want Resolved contribution source")
	}
	if got.Source.Kind != message.ContributionSourceKindAgentRuntime || got.Source.RefID != "msg_1" {
		t.Fatalf("Source = %#v, want agent runtime source for msg_1", got.Source)
	}
	if got.CreatedBy.Type != "agent" || got.CreatedBy.ID != "agt_1" || got.CreatedBy.Name != "Agent One" {
		t.Fatalf("CreatedBy = %#v, want compatibility actor derived from AuthorProfile", got.CreatedBy)
	}
	if got.EditedAt == nil || !got.EditedAt.Equal(editedAt) || got.EditedByMemberID != "mem_editor" || got.EditRevision != 2 {
		t.Fatalf("edit metadata = (%v, %q, %d), want edited task discussion metadata", got.EditedAt, got.EditedByMemberID, got.EditRevision)
	}
	if got.MessagePresentation == nil || got.MessagePresentation.Key != domain.MessagePresentationKeyWorkflowRecovery {
		t.Fatalf("MessagePresentation = %#v, want validated workflow recovery presentation", got.MessagePresentation)
	}
	encoded, err := json.Marshal(got)
	if err != nil {
		t.Fatal(err)
	}
	if !strings.Contains(string(encoded), `"messagePresentation"`) || strings.Contains(string(encoded), `"metadata"`) {
		t.Fatalf("discussion JSON = %s, want only safe presentation projection", encoded)
	}
}

func TestToTaskCarriesSourceProvenance(t *testing.T) {
	got := ToTask(taskboard.Task{
		ID: "tsk_source",
		Source: message.ContributionSource{
			Kind:    message.ContributionSourceKindHumanCompose,
			RefType: message.ContributionSourceRefTypeMessage,
			RefID:   "msg_task_source",
		},
		SourceThread: &taskboard.TaskSourceThread{
			ThreadChannelID: "thr_task_source",
			ParentChannelID: "chn_task_source",
			ParentMessageID: "msg_task_source",
			Ref:             "#task-source",
		},
	})

	if got.Source == nil {
		t.Fatalf("Source = nil, want Resolved task body contribution source")
	}
	if got.Source.Kind != message.ContributionSourceKindHumanCompose || got.Source.RefID != "msg_task_source" {
		t.Fatalf("Source = %#v, want human compose source for msg_task_source", got.Source)
	}
	if got.SourceThread == nil || got.SourceThread.ParentMessageID != "msg_task_source" {
		t.Fatalf("SourceThread = %#v, want compatibility navigation shape", got.SourceThread)
	}
}

func TestToRelatedTaskRowCarriesSourceProvenance(t *testing.T) {
	got := ToRelatedTaskRow(taskboard.RelatedTaskRow{
		TaskID:      "tsk_related_source",
		TaskScopeID: "tsk_scope_related_source",
		ChannelID:   "chn_related_source",
		TaskNumber:  9,
		Title:       "Related source",
		Status:      "todo",
		Source: message.ContributionSource{
			Kind:    message.ContributionSourceKindAgentRuntime,
			RefType: message.ContributionSourceRefTypeMessage,
			RefID:   "msg_related_source",
		},
	})

	if got.Source == nil || got.Source.Kind != message.ContributionSourceKindAgentRuntime || got.Source.RefID != "msg_related_source" {
		t.Fatalf("Source = %#v, want related task Resolved source", got.Source)
	}
}

func TestToTaskDiscussionEntryDerivesCompatibilityActorFromAuthorProfile(t *testing.T) {
	got := ToTaskDiscussionEntry(taskboard.TaskDiscussionEntry{
		ID:   "msg_service",
		Body: "service event discussion",
		AuthorProfile: message.AuthorProfile{
			ActorType:   message.AuthorActorTypeService,
			PrincipalID: "svc_install_1",
			MemberID:    "mem_service",
			TargetID:    "gitea",
			DisplayName: "Gitea",
			ServiceKind: "app",
			ServiceSlug: "gitea",
		},
		CreatedBy: taskboard.TaskActor{Type: "human", ID: "usr_legacy", Name: "Legacy User"},
	})

	if got.CreatedBy.Type != "app" || got.CreatedBy.ID != "svc_install_1" || got.CreatedBy.Name != "Gitea" {
		t.Fatalf("CreatedBy = %#v, want compatibility actor derived from Resolved AuthorProfile", got.CreatedBy)
	}
}

func TestToTaskArtifactDerivesCompatRefsFromProfiles(t *testing.T) {
	createdProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeService,
		PrincipalID: "svc_resolved",
		MemberID:    "mem_service",
		TargetID:    "gitea",
		DisplayName: "Gitea",
		ServiceKind: "app",
	}
	artifact := ToTaskArtifact(taskboard.TaskArtifact{
		ID:               "art_1",
		Kind:             "review_summary",
		Title:            "Summary",
		CreatedByProfile: &createdProfile,
		CreatedByRef:     "legacy_creator",
	})
	if artifact.CreatedByProfile == nil || artifact.CreatedByProfile.PrincipalID != "svc_resolved" {
		t.Fatalf("CreatedByProfile = %#v, want Resolved artifact creator profile", artifact.CreatedByProfile)
	}
	if artifact.CreatedByRef != "mem_service" {
		t.Fatalf("CreatedByRef = %q, want compatibility ref derived from Resolved profile", artifact.CreatedByRef)
	}
}

func TestToTaskCollaboratorDerivesCompatActorsFromProfiles(t *testing.T) {
	memberProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeAgent,
		PrincipalID: "agt_resolved",
		MemberID:    "mem_agent",
		DisplayName: "Resolved Agent",
	}
	addedByProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeHuman,
		PrincipalID: "usr_resolved",
		MemberID:    "mem_owner",
		DisplayName: "Resolved Owner",
	}
	removedByProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeService,
		PrincipalID: "svc_resolved",
		MemberID:    "mem_service",
		DisplayName: "Resolved Service",
		ServiceKind: "app",
	}

	got := ToTaskCollaborator(taskboard.TaskCollaborator{
		ID:                "collab_1",
		MemberID:          "mem_agent",
		MemberProfile:     &memberProfile,
		Member:            taskboard.TaskActor{Type: "human", ID: "usr_legacy", Name: "Legacy Member"},
		AddedByMemberID:   "mem_owner",
		AddedByProfile:    &addedByProfile,
		AddedBy:           taskboard.TaskActor{Type: "agent", ID: "agt_legacy", Name: "Legacy Adder"},
		RemovedByMemberID: "mem_service",
		RemovedByProfile:  &removedByProfile,
		RemovedBy:         &taskboard.TaskActor{Type: "human", ID: "usr_removed_legacy", Name: "Legacy Remover"},
	})

	if got.MemberProfile == nil || got.MemberProfile.PrincipalID != "agt_resolved" {
		t.Fatalf("MemberProfile = %#v, want Resolved collaborator member profile", got.MemberProfile)
	}
	if got.Member.Type != "agent" || got.Member.ID != "agt_resolved" || got.Member.Name != "Resolved Agent" {
		t.Fatalf("Member = %#v, want derived from Resolved member profile", got.Member)
	}
	if got.AddedByProfile == nil || got.AddedByProfile.MemberID != "mem_owner" {
		t.Fatalf("AddedByProfile = %#v, want Resolved addedBy profile", got.AddedByProfile)
	}
	if got.AddedBy.Type != "human" || got.AddedBy.ID != "usr_resolved" || got.AddedBy.Name != "Resolved Owner" {
		t.Fatalf("AddedBy = %#v, want derived from Resolved addedBy profile", got.AddedBy)
	}
	if got.RemovedByProfile == nil || got.RemovedByProfile.MemberID != "mem_service" {
		t.Fatalf("RemovedByProfile = %#v, want Resolved removedBy profile", got.RemovedByProfile)
	}
	if got.RemovedBy == nil || got.RemovedBy.Type != "app" || got.RemovedBy.ID != "svc_resolved" || got.RemovedBy.Name != "Resolved Service" {
		t.Fatalf("RemovedBy = %#v, want derived from Resolved removedBy profile", got.RemovedBy)
	}
}

func TestToCollaboratorListResponsesDeriveCompatActorsFromProfiles(t *testing.T) {
	ownerProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeHuman,
		PrincipalID: "usr_owner",
		MemberID:    "mem_owner",
		DisplayName: "Owner Profile",
	}
	memberProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeService,
		PrincipalID: "svc_member",
		MemberID:    "mem_service",
		DisplayName: "Service Profile",
		ServiceKind: "app",
	}

	agentList := ToListAgentCollaboratorsResponse(taskboard.ListAgentCollaboratorsResponse{
		ExecutionOwnerMemberID: "mem_owner",
		OwnerProfile:           &ownerProfile,
		Owner:                  taskboard.TaskActor{Type: "agent", ID: "agt_legacy_owner", Name: "Legacy Owner"},
		Collaborators: []taskboard.AgentCollaboratorSummary{{
			MemberID:      "mem_service",
			MemberProfile: &memberProfile,
			Member:        taskboard.TaskActor{Type: "human", ID: "usr_legacy_member", Name: "Legacy Member"},
		}},
	})
	if agentList.OwnerProfile == nil || agentList.OwnerProfile.MemberID != "mem_owner" {
		t.Fatalf("OwnerProfile = %#v, want Resolved owner profile", agentList.OwnerProfile)
	}
	if agentList.Owner.Type != "human" || agentList.Owner.ID != "usr_owner" || agentList.Owner.Name != "Owner Profile" {
		t.Fatalf("Owner = %#v, want derived from Resolved owner profile", agentList.Owner)
	}
	if got := agentList.Collaborators[0]; got.MemberProfile == nil || got.Member.Type != "app" || got.Member.ID != "svc_member" || got.Member.Name != "Service Profile" {
		t.Fatalf("Agent collaborator = %#v, want Resolved-derived member", got)
	}

	effective := ToListEffectiveTaskCollaboratorsResponse(taskboard.ListEffectiveTaskCollaboratorsResponse{
		ExecutionOwnerMemberID: "mem_owner",
		OwnerProfile:           &ownerProfile,
		Owner:                  taskboard.TaskActor{Type: "agent", ID: "agt_legacy_owner", Name: "Legacy Owner"},
		Collaborators: []taskboard.EffectiveTaskCollaborator{{
			MemberID:      "mem_service",
			MemberProfile: &memberProfile,
			Member:        taskboard.TaskActor{Type: "human", ID: "usr_legacy_member", Name: "Legacy Member"},
		}},
	})
	if effective.Owner.Type != "human" || effective.Owner.ID != "usr_owner" || effective.Owner.Name != "Owner Profile" {
		t.Fatalf("Effective owner = %#v, want derived from Resolved owner profile", effective.Owner)
	}
	if got := effective.Collaborators[0]; got.MemberProfile == nil || got.Member.Type != "app" || got.Member.ID != "svc_member" || got.Member.Name != "Service Profile" {
		t.Fatalf("Effective collaborator = %#v, want Resolved-derived member", got)
	}
}
func TestToPrivateAgentMentionCandidateDerivesOwnerCompatFromProfile(t *testing.T) {
	ownerProfile := message.AuthorProfile{
		ActorType:   message.AuthorActorTypeHuman,
		PrincipalID: "usr_owner_profile",
		MemberID:    "mem_owner_profile",
		DisplayName: "Resolved Owner",
	}

	got := ToPrivateAgentMentionCandidate(taskboard.PrivateAgentMentionCandidate{
		ID:               "agt_private",
		Name:             "private-agent",
		DisplayName:      "Private Agent",
		MemberID:         "mem_agent",
		OwnerProfile:     &ownerProfile,
		OwnerMemberID:    "mem_owner_legacy",
		OwnerUserID:      "usr_owner_legacy",
		OwnerName:        "Legacy Owner",
		OwnerDisplayName: "Legacy Owner",
	})

	if got.OwnerProfile == nil || got.OwnerProfile.MemberID != "mem_owner_profile" {
		t.Fatalf("OwnerProfile = %#v, want Resolved owner profile", got.OwnerProfile)
	}
	if got.OwnerMemberID != "mem_owner_profile" || got.OwnerUserID != "usr_owner_profile" {
		t.Fatalf("owner ids = (%q, %q), want Resolved profile ids", got.OwnerMemberID, got.OwnerUserID)
	}
	if got.OwnerDisplayName != "Resolved Owner" || got.OwnerName != "Resolved Owner" {
		t.Fatalf("owner names = (%q, %q), want Resolved display name", got.OwnerName, got.OwnerDisplayName)
	}
}

func TestToTaskActivityEventCarriesAuthorProfileAndSource(t *testing.T) {
	got := ToTaskActivityEvent(taskboard.TaskActivityEvent{
		ID:   "act_1",
		Type: "status_changed",
		AuthorProfile: message.AuthorProfile{
			ActorType:   message.AuthorActorTypeAgent,
			PrincipalID: "agt_1",
			MemberID:    "mem_agent",
			TargetID:    "agent-one",
			DisplayName: "Agent One",
		},
		Source: message.ContributionSource{
			Kind:      message.ContributionSourceKindAgentRuntime,
			RefType:   message.ContributionSourceRefTypeTaskActivity,
			RefID:     "act_1",
			EventType: "status_changed",
			Label:     "Agent One",
		},
		ActorRef:         "legacy_actor",
		ActorDisplayName: "Legacy Actor",
		SourceKind:       "message",
		SourceMessageID:  "legacy_msg",
		SourceActivityID: "legacy_activity",
	})

	if got.AuthorProfile == nil {
		t.Fatalf("AuthorProfile = nil, want Resolved activity author profile")
	}
	if got.AuthorProfile.ActorType != message.AuthorActorTypeAgent || got.AuthorProfile.DisplayName != "Agent One" {
		t.Fatalf("AuthorProfile = %#v, want agent profile", got.AuthorProfile)
	}
	if got.Source == nil || got.Source.RefType != message.ContributionSourceRefTypeTaskActivity || got.Source.RefID != "act_1" {
		t.Fatalf("Source = %#v, want task activity source", got.Source)
	}
	if got.ActorRef != "mem_agent" || got.ActorDisplayName != "Agent One" {
		t.Fatalf("compat actor = (%q, %q), want derived from AuthorProfile", got.ActorRef, got.ActorDisplayName)
	}
	if got.SourceKind != "activity" || got.SourceMessageID != "" || got.SourceActivityID != "act_1" {
		t.Fatalf("compat source = (%q, %q, %q), want derived from Resolved Source", got.SourceKind, got.SourceMessageID, got.SourceActivityID)
	}
}
