package pkulaw

import (
	"testing"

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

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

	require.Equal(t, []EndpointPolicy{
		{
			ID:       EndpointAggregate,
			Endpoint: "https://apim-gateway.pkulaw.com/mcp-law-agg/1.0.0/mcp",
			AllowedTools: []string{
				"search_article",
				"get_article",
				"get_law_list",
				"search_case",
				"get_case_list",
			},
		},
		{
			ID:       EndpointLawSemantic,
			Endpoint: "https://apim-gateway.pkulaw.com/mcp-law-search-service/mcp",
			AllowedTools: []string{
				"search_article",
				"get_article",
			},
		},
		{
			ID:       EndpointLawKeyword,
			Endpoint: "https://apim-gateway.pkulaw.com/mcp-law/mcp",
			AllowedTools: []string{
				"get_law_list",
			},
		},
		{
			ID:       EndpointCaseSemantic,
			Endpoint: "https://apim-gateway.pkulaw.com/mcp-case-search-service/mcp",
			AllowedTools: []string{
				"search_case",
			},
		},
		{
			ID:       EndpointCaseKeyword,
			Endpoint: "https://apim-gateway.pkulaw.com/mcp-case/mcp",
			AllowedTools: []string{
				"get_case_list",
			},
		},
	}, EndpointPolicies())

	policies := EndpointPolicies()
	policies[0].Endpoint = "https://attacker.invalid/mcp"
	policies[0].AllowedTools[0] = "call_tool"
	require.Equal(
		t,
		"https://apim-gateway.pkulaw.com/mcp-law-agg/1.0.0/mcp",
		EndpointPolicies()[0].Endpoint,
	)
	require.Equal(
		t,
		"search_article",
		EndpointPolicies()[0].AllowedTools[0],
	)
}

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

	require.Equal(t, map[string]ActionRoute{
		ActionSearchLawArticles: {
			Endpoint: EndpointAggregate,
			Tool:     "search_article",
		},
		ActionGetLawArticle: {
			Endpoint: EndpointAggregate,
			Tool:     "get_article",
		},
		ActionSearchLaws: {
			Endpoint: EndpointAggregate,
			Tool:     "get_law_list",
		},
		ActionSearchCases: {
			Endpoint: EndpointAggregate,
			Tool:     "search_case",
		},
		ActionSearchCaseDocuments: {
			Endpoint: EndpointAggregate,
			Tool:     "get_case_list",
		},
	}, cloneRoutes(aggregateRoutes))
	require.Equal(t, map[string]ActionRoute{
		ActionSearchLawArticles: {
			Endpoint: EndpointLawSemantic,
			Tool:     "search_article",
		},
		ActionGetLawArticle: {
			Endpoint: EndpointLawSemantic,
			Tool:     "get_article",
		},
		ActionSearchLaws: {
			Endpoint: EndpointLawKeyword,
			Tool:     "get_law_list",
		},
		ActionSearchCases: {
			Endpoint: EndpointCaseSemantic,
			Tool:     "search_case",
		},
		ActionSearchCaseDocuments: {
			Endpoint: EndpointCaseKeyword,
			Tool:     "get_case_list",
		},
	}, cloneRoutes(fallbackRoutes))
}

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

	contract := ConnectionConfigContract()
	require.Equal(t, []string{
		TopologyAggregate,
		TopologyFallback,
	}, contract.Fields[0].Values)
	require.Equal(t, "topology", contract.Fields[0].Name)
	require.True(t, contract.Fields[0].Required)
	require.NoError(t, contract.Validate(aggregateConnectionConfig()))
	require.NoError(t, contract.Validate(fallbackConnectionConfig()))

	for _, invalid := range []map[string]string{
		nil,
		{},
		{"topology": "dynamic"},
		{"topology": TopologyAggregate, "endpoint": "aggregate"},
		{"tool": "search_article"},
	} {
		require.Error(t, contract.Validate(invalid))
	}

	contract.Fields[0].Values[0] = "attacker"
	require.Equal(
		t,
		TopologyAggregate,
		ConnectionConfigContract().Fields[0].Values[0],
	)
}
