package exec

import (
	"bytes"
	"errors"
	"fmt"
	"log/slog"
	"testing"

	"github.com/stretchr/testify/require"

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

func TestExecAuthorizationFailureReasonUsesSafeEnums(t *testing.T) {
	tests := []struct {
		err  error
		want string
	}{
		{token.ErrExpired, "expired"},
		{token.ErrAgentTokenRevoked, "revoked"},
		{token.ErrAgentTokenInactive, "inactive"},
		{token.ErrAgentTokenServerMismatch, "server_mismatch"},
		{token.ErrAgentTokenScopeMismatch, "scope_mismatch"},
		{token.ErrAgentMismatch, "agent_mismatch"},
		{token.ErrInvalidSignature, "invalid_signature"},
		{token.ErrInvalidFormat, "invalid_format"},
		{errors.New("unexpected internal detail"), "internal"},
	}
	for _, test := range tests {
		require.Equal(t, test.want, execAuthorizationFailureReason(test.err))
	}
}

func TestKnownExecAuthorizationFailuresExcludeInternalErrors(t *testing.T) {
	require.True(t, isKnownExecAuthorizationFailure(token.ErrExpired))
	require.True(t, isKnownExecAuthorizationFailure(token.ErrInvalidFormat))
	require.False(t, isKnownExecAuthorizationFailure(errors.New("database unavailable with secret detail")))
}

func TestExecAuthorizationDiagnosticsNeverLogRawErrorOrBearerMaterial(t *testing.T) {
	execAuthorizationWarnings.Lock()
	clear(execAuthorizationWarnings.last)
	execAuthorizationWarnings.Unlock()
	var output bytes.Buffer
	previous := slog.Default()
	slog.SetDefault(slog.New(slog.NewJSONHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})))
	t.Cleanup(func() { slog.SetDefault(previous) })

	logExecAuthorizationFailure(fmt.Errorf("wrapped secret-token: %w", token.ErrExpired))
	logExecAuthorizationFailure(errors.New("database failed with secret-token and /private/token/path"))

	logged := output.String()
	require.Contains(t, logged, `"reason":"expired"`)
	require.Contains(t, logged, `"reason":"internal"`)
	require.NotContains(t, logged, "secret-token")
	require.NotContains(t, logged, "/private/token/path")
}
