package main

import (
	"bytes"
	"io"
	"log/slog"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/versioning"
)

func TestRunVersionFlagsPrintBuildInfoWithoutLoadingConfig(t *testing.T) {
	t.Setenv("AGENTTEAM_CORE_STORAGE_DSN", "")
	setServerBuildInfoForTest(t, " v1.2.3 ", " abc123 ", " 2026-06-10T11:22:33Z ")

	for _, flag := range []string{"--version", "-v"} {
		t.Run(flag, func(t *testing.T) {
			var output bytes.Buffer

			exitCode := run([]string{flag}, &output, io.Discard)

			require.Equal(t, 0, exitCode)
			require.Equal(t, "agentteam-server v1.2.3\ncommit: abc123\nbuilt: 2026-06-10T11:22:33Z\n", output.String())
		})
	}
}

func TestRunWithoutVersionStillRequiresConfig(t *testing.T) {
	t.Setenv("AGENTTEAM_CORE_STORAGE_DSN", "")
	discardDefaultLoggerForTest(t)

	exitCode := run(nil, io.Discard, io.Discard)

	require.Equal(t, 1, exitCode)
}

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

	exitCode := run(nil, io.Discard, &bootstrap)

	require.Equal(t, 1, exitCode)
	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

	exitCode := run(nil, io.Discard, &bootstrap)

	require.Equal(t, 1, exitCode)
	require.Contains(t, bootstrap.String(), "agentteam bootstrap: initialize logging: mkdir:")
	require.NotContains(t, bootstrap.String(), parent)
}

func setServerBuildInfoForTest(t *testing.T, version, commit, buildTime string) {
	t.Helper()

	previousVersion := versioning.Version
	previousCommit := versioning.GitCommit
	previousBuildTime := versioning.BuildTime
	t.Cleanup(func() {
		versioning.Version = previousVersion
		versioning.GitCommit = previousCommit
		versioning.BuildTime = previousBuildTime
	})

	versioning.Version = version
	versioning.GitCommit = commit
	versioning.BuildTime = buildTime
}

func discardDefaultLoggerForTest(t *testing.T) {
	t.Helper()

	previous := slog.Default()
	slog.SetDefault(slog.New(slog.NewTextHandler(io.Discard, nil)))
	t.Cleanup(func() {
		slog.SetDefault(previous)
	})
}
