package proc

import (
	"fmt"
	"os/exec"
	"runtime"
	"testing"
	"time"
)

// sleeperCmd 返回一个会阻塞约 d 秒的跨平台命令。
func sleeperCmd(d int) *exec.Cmd {
	if runtime.GOOS == "windows" {
		return exec.Command("cmd", "/c", fmt.Sprintf("timeout /t %d /nobreak >nul", d))
	}
	return exec.Command("sh", "-c", fmt.Sprintf("sleep %d", d))
}

// TestGroup_TerminateKillsStartedProcess 验证完整生命周期：Prepare → Start →
// Adopt → TerminateGroup 能在 grace 内终止一个本应长跑的进程。
func TestGroup_TerminateKillsStartedProcess(t *testing.T) {
	g := NewGroup()
	cmd := sleeperCmd(30)
	g.Prepare(cmd)
	if err := cmd.Start(); err != nil {
		t.Fatalf("start: %v", err)
	}
	if err := g.Adopt(cmd); err != nil {
		t.Fatalf("adopt: %v", err)
	}
	defer g.Close()

	done := make(chan struct{})
	go func() {
		_ = cmd.Wait()
		close(done)
	}()

	g.TerminateGroup(done, 2*time.Second)

	select {
	case <-done:
		// 进程已终止，符合预期。
	case <-time.After(10 * time.Second):
		t.Fatal("process not terminated within 10s after TerminateGroup")
	}
}

// TestNewGroup_NotNil 守护 build tag 选择逻辑：任意平台都应返回非 nil Group。
func TestNewGroup_NotNil(t *testing.T) {
	if NewGroup() == nil {
		t.Fatal("NewGroup returned nil")
	}
}
