//go:build windows

package dashboard

import (
	"context"
	"errors"
	"log/slog"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

const toolchainWindowsKillTimeout = 5 * time.Second

func configureToolchainCommand(cmd *exec.Cmd) {
	if cmd == nil {
		return
	}
	cmd.Cancel = func() error {
		killToolchainCommand(cmd)
		return nil
	}
}

func killToolchainCommand(cmd *exec.Cmd) {
	if cmd == nil || cmd.Process == nil {
		return
	}
	pid := cmd.Process.Pid
	if err := terminateToolchainProcessTree(pid); err != nil {
		slog.Warn("failed to terminate toolchain process tree; falling back to direct process kill",
			"pid", pid,
			"error", err,
		)
		if killErr := cmd.Process.Kill(); killErr != nil && !errors.Is(killErr, os.ErrProcessDone) {
			slog.Warn("failed to directly kill toolchain process after taskkill fallback",
				"pid", pid,
				"error", killErr,
			)
		}
	}
}

func terminateToolchainProcessTree(pid int) error {
	if pid <= 0 {
		return nil
	}
	ctx, cancel := context.WithTimeout(context.Background(), toolchainWindowsKillTimeout)
	defer cancel()
	out, err := exec.CommandContext(ctx, "taskkill", "/T", "/F", "/PID", strconv.Itoa(pid)).CombinedOutput()
	if err == nil {
		return nil
	}
	lower := strings.ToLower(string(out))
	if strings.Contains(lower, "not found") || strings.Contains(lower, "not running") {
		return nil
	}
	return err
}
