package server

import (
	"context"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/tidbcloud/AgentTeam/dev/internal/config"
	"github.com/tidbcloud/AgentTeam/dev/internal/watch"
)

func TestSeedDefaultUserIsDisabledByDefault(t *testing.T) {
	var requests int
	server := httptest.NewServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
		requests++
	}))
	defer server.Close()

	seeded, err := seedDefaultUserIfEnabled(context.Background(), server.URL)
	if err != nil {
		t.Fatalf("seed default user: %v", err)
	}
	if seeded || requests != 0 {
		t.Fatalf("default-off seeding = %v, requests = %d", seeded, requests)
	}
}

func TestMeshXChangeTargetsOneUnifiedServerRebuild(t *testing.T) {
	repoRoot := t.TempDir()
	target := watch.ChangeTarget(repoRoot, repoRoot+"/internal/meshxruntime/runtime.go", nil)
	if target != watch.ChangeAgentTeam {
		t.Fatalf("meshx change target = %d, want unified agentteam target %d", target, watch.ChangeAgentTeam)
	}
}

func TestSeedDefaultUserRequiresLoopbackWhenEnabled(t *testing.T) {
	t.Setenv(seedDefaultUserEnv, "true")
	for _, serverURL := range []string{":3001", "http://0.0.0.0:3001", "https://agentteam.example.com"} {
		t.Run(serverURL, func(t *testing.T) {
			seeded, err := seedDefaultUserIfEnabled(context.Background(), serverURL)
			if err == nil {
				t.Fatalf("seed %q unexpectedly succeeded", serverURL)
			}
			if seeded {
				t.Fatalf("seed %q reported enabled after rejection", serverURL)
			}
		})
	}
}

func TestSeedDefaultUserAllowsExplicitLoopbackOptIn(t *testing.T) {
	t.Setenv(seedDefaultUserEnv, "true")
	var requests int
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		requests++
		if request.URL.Path != "/api/v1/auth/register" {
			t.Errorf("path = %q", request.URL.Path)
		}
		writer.WriteHeader(http.StatusConflict)
	}))
	defer server.Close()

	seeded, err := seedDefaultUserIfEnabled(context.Background(), server.URL)
	if err != nil {
		t.Fatalf("seed default user: %v", err)
	}
	if !seeded || requests != 1 {
		t.Fatalf("loopback seeding = %v, requests = %d", seeded, requests)
	}
}

func TestReadyTimeoutFromEnv(t *testing.T) {
	t.Setenv("AGENTTEAM_DEV_READY_TIMEOUT", "3")
	if got := readyTimeoutFromEnv(); got != 10*time.Second {
		t.Fatalf("timeout = %s, want minimum 10s", got)
	}
	t.Setenv("AGENTTEAM_DEV_READY_TIMEOUT", "45")
	if got := readyTimeoutFromEnv(); got != 45*time.Second {
		t.Fatalf("timeout = %s, want 45s", got)
	}
	t.Setenv("AGENTTEAM_DEV_READY_TIMEOUT", "invalid")
	if got := readyTimeoutFromEnv(); got != 120*time.Second {
		t.Fatalf("timeout = %s, want default 120s", got)
	}
}

func TestNextReadyDeadlineExtendsWhileLocalDDLIsRunning(t *testing.T) {
	now := time.Unix(100, 0)
	original := now.Add(5 * time.Second)
	if got := nextReadyDeadline(original, now, 30*time.Second, true); got != now.Add(30*time.Second) {
		t.Fatalf("deadline = %s, want DDL-aware extension", got)
	}
	if got := nextReadyDeadline(original, now, 30*time.Second, false); got != original {
		t.Fatalf("deadline = %s, want unchanged %s", got, original)
	}
}

func TestRunnerEnablesDDLAwareWaitingForLocalAGSDSN(t *testing.T) {
	runner := &Runner{cfg: &config.Config{
		MeshXAGSDatabaseDSN: "root@tcp(127.0.0.1:4000)/agentteam_ags",
	}}
	if !runner.IsLocalTiDB() {
		t.Fatal("local AGS TiDB DSN did not enable DDL-aware readiness")
	}
	runner.cfg.MeshXAGSDatabaseDSN = "root@tcp(db.example.com:4000)/agentteam_ags"
	if runner.IsLocalTiDB() {
		t.Fatal("remote AGS TiDB DSN enabled DDL-aware readiness")
	}
}
