package daemon

import (
	"context"
	"errors"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/runtimecontrol"
)

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

	userCtx := runtimecontrol.WithRemoteRequestContext(context.Background(), runtimecontrol.RemoteRequestContext{
		Origin: runtimecontrol.RemoteRequestOriginUserInteractive,
		Cause:  runtimecontrol.RemoteRequestCauseWebAPI,
	})
	invocation := RemoteEndpointInvocation[string]{Context: userCtx}.withDefaults()
	require.Equal(t, runtimecontrol.RemoteRequestOriginUserInteractive, invocation.RequestContext.Origin)
	require.Equal(t, runtimecontrol.RemoteRequestCauseWebAPI, invocation.RequestContext.Cause)

	background := RemoteEndpointInvocation[string]{}.withDefaults()
	require.Equal(t, runtimecontrol.RemoteRequestOriginBackground, background.RequestContext.Origin)
	require.Equal(t, runtimecontrol.RemoteRequestCauseUnknown, background.RequestContext.Cause)
}

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

	descriptor, ok := defaultRemoteEndpointRegistry().Lookup(remoteEndpointMachineDirectoryList, 1)
	require.True(t, ok)
	require.Equal(t, commandFallbackNone, descriptor.FallbackCommand)
	descriptor.LinkPolicy = RemoteEndpointLinkPolicyElasticRequired

	invocation := RemoteEndpointInvocation[string]{
		Context:    context.Background(),
		Client:     newElasticReadyClient(),
		Manager:    newTestElasticRequestLinkManager(t, nil, ElasticRequestLinkManagerConfig{}),
		Descriptor: descriptor,
		Fallback: func() (string, error) {
			t.Fatal("fallback must not run for elastic-required endpoint without fallback command")
			return "", nil
		},
	}.withDefaults()

	value, err := invocation.elasticFailureFallback(RemoteRequestStableErrorDesktopUnavailable, "connect_timeout")
	require.Empty(t, value)
	require.Error(t, err)
	require.ErrorIs(t, err, remoteRequestStableError(RemoteRequestStableErrorDesktopUnavailable))

	var connectionErr *RemoteEndpointConnectionError
	require.True(t, errors.As(err, &connectionErr))
	require.Equal(t, remoteEndpointMachineDirectoryList, connectionErr.EndpointID)
	require.Equal(t, "connect_timeout", connectionErr.Reason)
	require.Equal(t, RemoteRequestStableErrorDesktopUnavailable, connectionErr.Stable)
	require.Equal(t, string(RemoteRequestStableErrorDesktopUnavailable), err.Error())
}
