package agent

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/alertstore/pkg/alert"
)

// The verdict vocabulary is only worth having if it pairs with the resolution
// the human eventually records. If someone renames one side, agreement queries
// start returning nothing rather than failing, so the pairing is asserted here.
func TestVerdictsPairWithResolutions(t *testing.T) {
	t.Parallel()

	pairs := map[string]string{
		VerdictNoise:         alert.ResolutionNoise,
		VerdictSelfRecovered: alert.ResolutionSelfRecovered,
		VerdictEscalation:    alert.ResolutionHandled,
	}
	for verdict, resolution := range pairs {
		require.True(t, ValidVerdict(verdict))
		require.NotEmpty(t, resolution)
	}
	// Mitigated is scored by override rather than by resolution, and unknown
	// has no counterpart on purpose: an agent that cannot tell must be able to
	// say so rather than being pushed into one of the three.
	require.True(t, ValidVerdict(VerdictMitigated))
	require.True(t, ValidVerdict(VerdictUnknown))
	require.Len(t, pairs, 3)
}

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

	require.False(t, ValidVerdict(""))
	require.False(t, ValidVerdict("likely_noise")) // the pre-000008 spelling
	require.False(t, ValidVerdict("handled"))      // the resolution, not the verdict
	require.False(t, ValidVerdict("probably"))     // anything else
}

// An agent may report that it started, finished or failed. It may not put a run
// back to dispatched, which would erase the fact that it had begun.
func TestValidStatus(t *testing.T) {
	t.Parallel()

	require.True(t, ValidStatus(StatusRunning))
	require.True(t, ValidStatus(StatusSucceeded))
	require.True(t, ValidStatus(StatusFailed))
	require.False(t, ValidStatus(StatusDispatched))
	require.False(t, ValidStatus(""))
}

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

	require.False(t, (&Run{Status: StatusDispatched}).Terminal())
	require.False(t, (&Run{Status: StatusRunning}).Terminal())
	require.True(t, (&Run{Status: StatusSucceeded}).Terminal())
	require.True(t, (&Run{Status: StatusFailed}).Terminal())
}
