package dispatcher

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

func TestSessionResumeGuardLegacyWorkspaceWriteDefaultsFullAccess(t *testing.T) {
	current := newRuntimePolicySnapshot("opencode", "opencode", types.AgentPermissionModeWorkspaceWrite, 2)
	decision := evaluateSessionResumeGuard(current, sessionResumeState{
		LastStartConfig: &types.AgentStartConfig{PermissionMode: types.AgentPermissionModeFullAccess, SessionID: "sess-old"},
	})

	require.Equal(t, sessionResumeGuardReuse, decision.Action)
	require.True(t, decision.PersistCurrentPolicy)
}

func TestSessionResumeGuardLegacyStateAllowsFullAccessAndPersistsPolicy(t *testing.T) {
	current := newRuntimePolicySnapshot("codex", "codex", types.AgentPermissionModeFullAccess, 1)
	decision := evaluateSessionResumeGuard(current, sessionResumeState{
		LastStartConfig: &types.AgentStartConfig{PermissionMode: types.AgentPermissionModeFullAccess, SessionID: "sess-full"},
	})

	require.Equal(t, sessionResumeGuardReuse, decision.Action)
	require.True(t, decision.PersistCurrentPolicy)
}

func TestSessionResumeGuardMatchingPolicyAllowsReuse(t *testing.T) {
	current := newRuntimePolicySnapshot("codex", "codex", types.AgentPermissionModeWorkspaceWrite, 4)
	decision := evaluateSessionResumeGuard(current, sessionResumeState{
		LastRuntimePolicy:            &current,
		LastRuntimePolicyFingerprint: current.Fingerprint,
		LastRuntimePolicyGeneration:  current.Generation,
		LastSessionID:                "sess-current",
	})

	require.Equal(t, sessionResumeGuardReuse, decision.Action)
	require.False(t, decision.PersistCurrentPolicy)
}

func TestSessionResumeGuardGenerationMismatchClears(t *testing.T) {
	previous := newRuntimePolicySnapshot("codex", "codex", types.AgentPermissionModeWorkspaceWrite, 3)
	current := newRuntimePolicySnapshot("codex", "codex", types.AgentPermissionModeWorkspaceWrite, 4)
	decision := evaluateSessionResumeGuard(current, sessionResumeState{LastRuntimePolicy: &previous})

	require.Equal(t, sessionResumeGuardClearAndFreshStart, decision.Action)
	require.Contains(t, decision.Reason, "generation")
}

func TestInvalidateResumeStateForRuntimePolicyClearsSensitiveFieldsOnly(t *testing.T) {
	current := newRuntimePolicySnapshot("opencode", "opencode", types.AgentPermissionModeWorkspaceWrite, 7)
	state := &sessionResumeState{
		LastSessionID:     "sess-old",
		SessionResumeSafe: true,
		LastStartConfig: &types.AgentStartConfig{
			Name:                    "Agent",
			Runtime:                 "opencode",
			PermissionMode:          types.AgentPermissionModeFullAccess,
			Model:                   "saved-model",
			ReasoningEffort:         "high",
			InstructionsFingerprint: "old-fingerprint",
			ServerURL:               "https://old.example.com",
			AuthToken:               "old-token",
			SessionID:               "sess-old",
		},
		ActiveTaskTarget: types.ActiveTaskTarget{Source: "task", Channel: "agentteam", TaskNumber: 1},
		DeferredDeliveries: []deferredDeliveryEntry{{
			MessageID: "msg-deferred",
		}},
	}

	invalidateResumeStateForRuntimePolicy(state, current)

	require.Empty(t, state.LastSessionID)
	require.False(t, state.SessionResumeSafe)
	require.NotNil(t, state.LastStartConfig)
	require.Equal(t, "Agent", state.LastStartConfig.Name)
	require.Equal(t, "saved-model", state.LastStartConfig.Model)
	require.Equal(t, "high", state.LastStartConfig.ReasoningEffort)
	require.Empty(t, state.LastStartConfig.Runtime)
	require.Empty(t, state.LastStartConfig.PermissionMode)
	require.Empty(t, state.LastStartConfig.InstructionsFingerprint)
	require.Empty(t, state.LastStartConfig.ServerURL)
	require.Empty(t, state.LastStartConfig.AuthToken)
	require.Empty(t, state.LastStartConfig.SessionID)
	require.Equal(t, "agentteam", state.ActiveTaskTarget.Channel)
	require.Equal(t, int64(1), state.ActiveTaskTarget.TaskNumber)
	require.Len(t, state.DeferredDeliveries, 1)
	require.Equal(t, current.Fingerprint, state.LastRuntimePolicyFingerprint)
	require.Equal(t, current.Generation, state.LastRuntimePolicyGeneration)
	require.NotNil(t, state.LastRuntimePolicy)
}
