//go:build !windows

package infra

import (
	"time"
)

// ProcessWait waits for a subprocess to finish and collects its output.
// If timeoutSec > 0 and the process has not exited by then, ProcessKill is
// called with graceSec=5 and the result is marked Killed=true.
func ProcessWait(handle *ProcessHandle, timeoutSec int) (ProcessResult, error) {
	// Wait for the process in a goroutine.
	waitCh := make(chan error, 1)
	go func() {
		waitCh <- handle.Cmd.Wait()
	}()

	killed := false

	if timeoutSec > 0 {
		timer := time.NewTimer(time.Duration(timeoutSec) * time.Second)
		defer timer.Stop()
		select {
		case <-timer.C:
			// Timeout exceeded — kill the process group.
			_ = ProcessKill(handle, 5)
			killed = true
			<-waitCh
		case <-waitCh:
		}
	} else {
		<-waitCh
	}

	// After Wait() returns, buffers are safe to read.
	exitCode := 0
	if handle.Cmd.ProcessState != nil {
		exitCode = handle.Cmd.ProcessState.ExitCode()
	} else if killed {
		exitCode = -1
	}

	duration := time.Since(handle.StartTime)

	return ProcessResult{
		ExitCode:   exitCode,
		Stdout:     handle.stdout.String(),
		Stderr:     handle.stderr.String(),
		DurationMs: duration.Milliseconds(),
		Killed:     killed,
	}, nil
}
