package app

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/store/access"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
)

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

	for _, path := range []string{
		"agent_target_resolution.go",
		"agent_target_basis.go",
		"messaging_adapter.go",
	} {
		source, err := os.ReadFile(filepath.Join(".", path))
		require.NoError(t, err)
		text := string(source)
		require.NotContains(t, text, "ownerPrivateAgentTarget"+"Re"+"coveryAllowed")
		require.NotContains(t, text, "resolveOwnerPrivateAgent"+"SendTarget")
		require.NotContains(t, text, "resolveOwnerPrivateAgent"+"HistoryThread")
		require.NotContains(t, text, "RequireOwnerPrivateContextRecordVisible")
	}
}

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

	require.False(t, agentTargetBasis{Visibility: "public"}.Private())
	require.False(t, agentTargetBasis{Visibility: "private"}.Private())
	require.True(t, agentTargetBasis{Visibility: "private", OwnerMemberID: "mem-owner"}.Private())
}

// TestAgentTaskScopeTargetBasisRecordsBoardChannelScope asserts that the raw
// task-scope target resolution records task_board_channel with the actual
// authoritative board Channel scope (from the active Task/board authority),
// never the Task scope. The Task scope is only target identity (storage/
// delivery/read), while the permission basis names the Channel whose membership
// actually authorized the operation.
func TestAgentTaskScopeTargetBasisRecordsBoardChannelScope(t *testing.T) {
	t.Parallel()

	auth := agent.AuthenticatedAgent{
		AgentID:     "agt_test",
		WorkspaceID: "wsp_test",
		MemberID:    "mem_agent",
	}
	request := agentScopeTargetRequest{
		Raw:         "#tsk_task_scope",
		TaskScopeID: "tsk_task_scope",
		IsRawTask:   true,
		Requested: access.ScopeTargetRef{
			Kind: access.ScopeTargetKindTask,
			Ref:  "tsk_task_scope",
		},
	}

	writeTarget, err := newAgentTaskScopeTarget(auth, request, "tsk_task_scope", "chn_task_board", access.ScopeTargetOperationTaskDiscussion, agentTargetResolutionRoleWrite)
	require.NoError(t, err)
	// Target identity stays the Task scope.
	require.Equal(t, access.ScopeRef{ScopeID: "tsk_task_scope", ScopeType: access.ScopeTargetKindTask}, writeTarget.StorageScope)
	require.Equal(t, writeTarget.StorageScope, writeTarget.DeliveryScope)
	// The permission basis records the actual authoritative board Channel scope.
	require.Len(t, writeTarget.PermissionBasis, 1)
	require.Equal(t, access.ScopePermissionBasisTaskBoardChannel, writeTarget.PermissionBasis[0].Kind)
	require.Equal(t, access.ScopeRef{ScopeID: "chn_task_board", ScopeType: access.ScopeTargetKindChannel}, writeTarget.PermissionBasis[0].Scope)
	require.Equal(t, "mem_agent", writeTarget.PermissionBasis[0].MemberID)
	require.Equal(t, "task board channel membership", writeTarget.PermissionBasis[0].Reason)

	readTarget, err := newAgentTaskScopeTarget(auth, request, "tsk_task_scope", "chn_task_board", access.ScopeTargetOperationMessageRead, agentTargetResolutionRoleRead)
	require.NoError(t, err)
	require.Equal(t, access.ScopeRef{ScopeID: "tsk_task_scope", ScopeType: access.ScopeTargetKindTask}, readTarget.ReadScope)
	require.Equal(t, access.ScopePermissionBasisTaskBoardChannel, readTarget.PermissionBasis[0].Kind)
	require.Equal(t, access.ScopeRef{ScopeID: "chn_task_board", ScopeType: access.ScopeTargetKindChannel}, readTarget.PermissionBasis[0].Scope)
}
