package acp

import (
	"encoding/json"
	"log/slog"
	"testing"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func marshalServers(t *testing.T, servers []any) string {
	t.Helper()
	b, err := json.Marshal(servers)
	require.NoError(t, err)
	return string(b)
}

func TestBuildMcpServers_AcwInjectedWithHTTPCapability(t *testing.T) {
	t.Parallel()
	out := buildMcpServers(nil, "http://x/mcp", "tok123", true, false, slog.Default(), uuid.New())
	require.Len(t, out, 1)

	j := marshalServers(t, out)
	assert.Contains(t, j, `"type":"http"`)
	assert.Contains(t, j, `"name":"acw"`)
	assert.Contains(t, j, `"url":"http://x/mcp"`)
	assert.Contains(t, j, `{"name":"Authorization","value":"Bearer tok123"}`)
}

func TestBuildMcpServers_AcwSkippedWithoutCapabilityOrConfig(t *testing.T) {
	t.Parallel()
	// 无 http 能力 → 跳过自家 MCP
	out := buildMcpServers(nil, "http://x/mcp", "tok", false, false, slog.Default(), uuid.New())
	assert.Empty(t, out)
	// 未配置 public_url / token → 不注入
	out = buildMcpServers(nil, "", "tok", true, true, slog.Default(), uuid.New())
	assert.Empty(t, out)
	out = buildMcpServers(nil, "http://x/mcp", "", true, true, slog.Default(), uuid.New())
	assert.Empty(t, out)
}

func TestBuildMcpServers_StdioBaselineNoTypeField(t *testing.T) {
	t.Parallel()
	specs := []McpServerSpec{{
		Name: "fs", Type: McpStdio, Command: "/bin/mcp-fs",
		Env: map[string]string{"B": "2", "A": "1"},
	}}
	// stdio 不受能力门控（http/sse 均 false 仍下发）
	out := buildMcpServers(specs, "", "", false, false, slog.Default(), uuid.New())
	require.Len(t, out, 1)

	j := marshalServers(t, out)
	// ACP v1：stdio 无 type 判别字段；args/env 必填（空数组）；env 按 key 排序
	assert.NotContains(t, j, `"type"`)
	assert.Contains(t, j, `"command":"/bin/mcp-fs"`)
	assert.Contains(t, j, `"args":[]`)
	assert.Contains(t, j, `"env":[{"name":"A","value":"1"},{"name":"B","value":"2"}]`)
}

func TestBuildMcpServers_CapabilityFiltering(t *testing.T) {
	t.Parallel()
	specs := []McpServerSpec{
		{Name: "h", Type: McpHTTP, URL: "http://h"},
		{Name: "s", Type: McpSSE, URL: "http://s"},
		{Name: "io", Type: McpStdio, Command: "/x"},
	}

	// 仅 http 能力：sse 条目被跳过
	out := buildMcpServers(specs, "", "", true, false, slog.Default(), uuid.New())
	j := marshalServers(t, out)
	require.Len(t, out, 2)
	assert.Contains(t, j, `"name":"h"`)
	assert.NotContains(t, j, `"name":"s"`)
	assert.Contains(t, j, `"name":"io"`)

	// 全能力：全部下发，sse 条目 type 正确
	out = buildMcpServers(specs, "", "", true, true, slog.Default(), uuid.New())
	require.Len(t, out, 3)
	assert.Contains(t, marshalServers(t, out), `"type":"sse"`)
}
