package server

import (
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/config"
	"gopkg.in/yaml.v3"
)

type deliverySplitCompose struct {
	Services map[string]deliverySplitService `yaml:"services"`
}

type deliverySplitService struct {
	Image       string            `yaml:"image"`
	Command     []string          `yaml:"command"`
	Environment map[string]string `yaml:"environment"`
	Volumes     []string          `yaml:"volumes"`
}

func TestDeliverySplitComposeUsesFinalResolverTopology(t *testing.T) {
	t.Parallel()
	content, err := os.ReadFile(filepath.Join("..", "..", "docker-compose.delivery-split.yml"))
	require.NoError(t, err)
	var compose deliverySplitCompose
	require.NoError(t, yaml.Unmarshal(content, &compose))

	central := compose.Services["agentteam-central"]
	require.Equal(t, "central", central.Environment["AGENTTEAM_SERVER_PROFILE"])
	require.Empty(t, central.Environment["AGENTTEAM_MESHX_BASE_URL"])
	require.Empty(t, central.Volumes)
	require.Empty(t, meshXSecretEnvironment(central.Environment))

	gateway := compose.Services["agentteam-gateway"]
	require.Equal(t, []string{"/app/bin/agentteam-gateway-server"}, gateway.Command)
	defaultGroup := config.DefaultWorkspaceGroupID
	require.Empty(t, gateway.Environment["AGENTTEAM_DEFAULT_WORKSPACE_GROUP_ID"])
	require.Contains(t, gateway.Environment["AGENTTEAM_GATEWAY_WORKSPACE_UPSTREAMS"], defaultGroup+"=http://agentteam-workspace-default:3001")
	require.Contains(t, gateway.Environment["AGENTTEAM_GATEWAY_WORKSPACE_IDENTITY_RESOLVER_URL"], "agentteam-workspace-default")
	require.Empty(t, gateway.Volumes)
	require.Empty(t, meshXSecretEnvironment(gateway.Environment))

	expectedVolumes := map[string]string{
		"agentteam-workspace-default": "meshx-data-default:/data",
		"agentteam-workspace-large-a": "meshx-data-large-a:/data",
	}
	for serviceName, groupID := range map[string]string{
		"agentteam-workspace-default": "workspace-default",
		"agentteam-workspace-large-a": "workspace-large-a",
	} {
		service := compose.Services[serviceName]
		require.Equal(t, "workspace", service.Environment["AGENTTEAM_SERVER_PROFILE"], serviceName)
		require.Equal(t, groupID, service.Environment["AGENTTEAM_WORKSPACE_GROUP_ID"], serviceName)
		require.Equal(t, defaultGroup, service.Environment["AGENTTEAM_DEFAULT_WORKSPACE_GROUP_ID"], serviceName)
		require.NotEmpty(t, service.Environment["MESHX_DATABASE_DSN"], serviceName)
		require.Contains(t, service.Volumes, expectedVolumes[serviceName], serviceName)
	}
	require.NotEqual(t, expectedVolumes["agentteam-workspace-default"], expectedVolumes["agentteam-workspace-large-a"])

	schema := compose.Services["agentteam-schema"]
	require.Equal(t, "agentteam-server:delivery-split", schema.Image)
	require.Equal(t, []string{"/app/bin/agentteam-schema", "init"}, schema.Command)
	for _, key := range []string{"AGENTTEAM_DATABASE_DSN", "MESHX_DATABASE_DSN", "MESHX_AGS_DATABASE_DSN"} {
		require.NotEmpty(t, schema.Environment[key], key)
	}
}

func meshXSecretEnvironment(environment map[string]string) []string {
	var keys []string
	for key := range environment {
		if strings.HasPrefix(key, "MESHX_") {
			keys = append(keys, key)
		}
	}
	return keys
}
