package jin10

import (
	"sort"
	"testing"

	"github.com/stretchr/testify/require"
)

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

	definition := Definition()
	require.Equal(t, Domain, definition.Domain)
	require.Equal(t, 1, definition.Version)
	require.Equal(t, "Jin10", definition.Name)

	wantNames := []string{
		ActionListQuoteCodes,
		ActionGetQuote,
		ActionGetKline,
		ActionListFlash,
		ActionSearchFlash,
		ActionListNews,
		ActionSearchNews,
		ActionGetNews,
		ActionListCalendar,
	}
	gotNames := make([]string, 0, len(definition.Actions))
	for _, action := range definition.Actions {
		gotNames = append(gotNames, action.Name)
		require.Equal(t, "read", action.Safety.Class)
		require.True(t, action.Safety.Idempotent)
		require.False(t, action.Safety.Destructive)
		require.Equal(t, schemaDialect, action.InputSchema["$schema"])
		require.Equal(t, schemaDialect, action.OutputSchema["$schema"])
	}
	require.Equal(t, wantNames, gotNames)
}

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

	var countSchema map[string]any
	for _, action := range Definition().Actions {
		if action.Name != ActionGetKline {
			continue
		}
		properties, ok := action.InputSchema["properties"].(map[string]any)
		require.True(t, ok)
		countSchema, ok = properties["count"].(map[string]any)
		require.True(t, ok)
	}
	require.Equal(t, 1, countSchema["minimum"])
	require.Equal(t, 100, countSchema["maximum"])
}

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

	want := []string{
		"get_kline",
		"get_news",
		"get_quote",
		"list_calendar",
		"list_flash",
		"list_news",
		"search_flash",
		"search_news",
	}
	sort.Strings(want)
	require.Equal(t, want, allowedToolNames())
}

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

	actions := make(map[string]map[string]any)
	for _, action := range Definition().Actions {
		actions[action.Name] = action.OutputSchema
	}
	quoteProperties := actions[ActionListQuoteCodes]["properties"].(map[string]any)
	quoteData := quoteProperties["data"].(map[string]any)
	require.NotContains(t, quoteData, "minItems")

	klineProperties := actions[ActionGetKline]["properties"].(map[string]any)
	klineData := klineProperties["data"].(map[string]any)
	klineChoices := klineData["anyOf"].([]any)
	klineObject := klineChoices[1].(map[string]any)
	klineObjectProperties := klineObject["properties"].(map[string]any)
	klines := klineObjectProperties["klines"].(map[string]any)
	require.NotContains(t, klines, "maxItems")
}
