package mcpserver

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/aisupport/apps/cli/operation-mcp/devops"
)

func TestSnakeCase(t *testing.T) {
	require.Equal(t, "restart_changefeed", snakeCase("RestartChangefeed"))
	require.Equal(t, "submit_restart_changefeed", toolNameFor("RestartChangefeed"))
	require.Equal(t, "scale_cluster_pd_size", snakeCase("ScaleClusterPDSize"))
	require.Equal(t, "deploy_new_byoc_region", snakeCase("DeployNewBYOCRegion"))
}

func TestOperationInputSchema(t *testing.T) {
	op, ok := testCatalog().Get("RestartChangefeed")
	require.True(t, ok)

	schema, err := operationInputSchema(op)
	require.NoError(t, err)
	require.Equal(t, "object", schema["type"])
	require.Equal(t, false, schema["additionalProperties"])
	require.ElementsMatch(t, []string{"reason", "changefeed_id", "cluster_type"}, schema["required"])

	properties, ok := schema["properties"].(map[string]any)
	require.True(t, ok)
	require.NotContains(t, properties, "oncall_category", "const params are injected, not asked for")

	clusterType, ok := properties["cluster_type"].(map[string]any)
	require.True(t, ok)
	require.Equal(t, "string", clusterType["type"])
	require.Equal(t, []string{"CHANGEFEED", "CHANGEFEED_NG"}, clusterType["enum"])

	startPolicy, ok := properties[fieldStartPolicy].(map[string]any)
	require.True(t, ok)
	require.Equal(t, string(devops.DefaultStartPolicy), startPolicy["default"])
}

func TestOperationInputSchemaMapsParamTypes(t *testing.T) {
	def := paramSchema(devops.ParamDefine{Type: devops.ParamTypeInt, Default: strPtr("3")})
	require.Equal(t, "integer", def["type"])
	require.Equal(t, int64(3), def["default"])

	def = paramSchema(devops.ParamDefine{Type: devops.ParamTypeMap})
	require.Equal(t, "object", def["type"])
	require.Equal(t, map[string]any{"type": "string"}, def["additionalProperties"])

	def = paramSchema(devops.ParamDefine{Type: devops.ParamTypeString, MultiEnum: []string{"tidb", "tikv"}})
	require.Equal(t, "string", def["type"])
	require.Contains(t, def["description"], "Comma-separated subset of: tidb, tikv.")
}

func TestOperationInputSchemaRejectsReservedParamName(t *testing.T) {
	op := &devops.Operation{
		Name:    "WeirdOperation",
		Actions: []devops.OperationAction{{Name: "Weird"}},
		Params:  map[string]devops.ParamDefine{fieldReason: {Type: devops.ParamTypeString}},
	}

	_, err := operationInputSchema(op)
	require.ErrorContains(t, err, "collides with a reserved field")
}
