package main

import (
	"bytes"
	"context"
	"os"
	"path/filepath"
	"testing"

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

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

	upstreams, err := parseWorkspaceUpstreams(" workspace-default = http://agentteam-workspace-server:3001 , workspace-large-a=http://agentteam-workspace-server-large-a:3001 ")
	require.NoError(t, err)
	require.Equal(t, map[string]string{
		"workspace-default": "http://agentteam-workspace-server:3001",
		"workspace-large-a": "http://agentteam-workspace-server-large-a:3001",
	}, upstreams)
}

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

	_, err := parseWorkspaceUpstreams("workspace-default")
	require.EqualError(t, err, "parse AGENTTEAM_GATEWAY_WORKSPACE_UPSTREAMS item \"workspace-default\": expected group=url")

	_, err = parseWorkspaceUpstreams("workspace-default=")
	require.EqualError(t, err, "parse AGENTTEAM_GATEWAY_WORKSPACE_UPSTREAMS item \"workspace-default=\": group and url are required")
}

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

	upstreams := map[string]string{
		"workspace-default": "http://agentteam-workspace-server:3001/base/",
		"workspace-large-a": "http://agentteam-workspace-server-large-a:3001",
	}

	derived, err := resolveWorkspaceIdentityResolverURL("", "workspace-default", upstreams)
	require.NoError(t, err)
	require.Equal(t, "http://agentteam-workspace-server:3001/base/internal/meshxruntime/workspace-route-identity", derived)

	explicit, err := resolveWorkspaceIdentityResolverURL(" https://resolver.example.test/custom ", "workspace-default", upstreams)
	require.NoError(t, err)
	require.Equal(t, "https://resolver.example.test/custom", explicit)
}

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

	_, err := resolveWorkspaceIdentityResolverURL("", "workspace-default", map[string]string{
		"workspace-large-a": "http://agentteam-workspace-server-large-a:3001",
	})
	require.EqualError(t, err, `derive gateway workspace identity resolver URL: default workspace group "workspace-default" has no configured workspace upstream`)
}

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

	var output bytes.Buffer
	exitCode := handleHelp([]string{"--help"}, &output)

	require.Equal(t, 0, exitCode)
	require.Contains(t, output.String(), "Usage: agentteam-gateway-server")
	require.Contains(t, output.String(), "AGENTTEAM_GATEWAY_CENTRAL_UPSTREAM_URL")
	require.Contains(t, output.String(), "Optional environment:")
	require.Contains(t, output.String(), "AGENTTEAM_GATEWAY_WORKSPACE_IDENTITY_RESOLVER_URL")
}

func TestRunReportsBootstrapConfigFailure(t *testing.T) {
	t.Setenv("AGENTTEAM_LOG_LEVEL", "verbose")
	var bootstrap bytes.Buffer

	err := run(context.Background(), &bootstrap)

	require.EqualError(t, err, "load config: AGENTTEAM_LOG_LEVEL must be one of debug, info, warn, or error")
	require.Equal(t, "agentteam bootstrap: load config: AGENTTEAM_LOG_LEVEL must be one of debug, info, warn, or error\n", bootstrap.String())
}

func TestRunReportsBootstrapLogOpenFailureWithoutPath(t *testing.T) {
	t.Setenv("AGENTTEAM_DATABASE_DSN", "root:@tcp(127.0.0.1:4000)/agentteam?tls=false")
	t.Setenv("AGENTTEAM_LOG_LEVEL", "info")
	t.Setenv("AGENTTEAM_LOG_OUTPUT", "file")
	parent := filepath.Join(t.TempDir(), "not-a-directory")
	require.NoError(t, os.WriteFile(parent, []byte("x"), 0o600))
	t.Setenv("AGENTTEAM_LOG_FILE", filepath.Join(parent, "agentteam.log"))
	var bootstrap bytes.Buffer

	err := run(context.Background(), &bootstrap)

	require.ErrorContains(t, err, "initialize logging")
	require.Contains(t, bootstrap.String(), "agentteam bootstrap: initialize logging: mkdir:")
	require.NotContains(t, bootstrap.String(), parent)
}
