// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import (
	"errors"
	"internal/testlog"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"time"
)

var (
	// ErrProcessDone indicates a [Process] has finished.
	ErrProcessDone = errors.New("os: process already finished")
	// errProcessReleased indicates a [Process] has been released.
	errProcessReleased = errors.New("os: process already released")
	// ErrNoHandle indicates a [Process] does not have a handle.
	ErrNoHandle = errors.New("os: process handle unavailable")
)

// processStatus describes the status of a [Process].
type processStatus uint32

const (
	// statusOK means that the Process is ready to use.
	statusOK processStatus = iota

	// statusDone indicates that the PID/handle should not be used because
	// the process is done (has been successfully Wait'd on).
	statusDone

	// statusReleased indicates that the PID/handle should not be used
	// because the process is released.
	statusReleased
)

// Process stores the information about a process created by [StartProcess].
type Process struct {
	Pid int

	// state contains the atomic process state.
	//
	// This consists of the processStatus fields,
	// which indicate if the process is done/released.
	state atomic.Uint32

	// Used only when handle is nil
	sigMu sync.RWMutex // avoid race between wait and signal

	// handle, if not nil, is a pointer to a struct
	// that holds the OS-specific process handle.
	// This pointer is set when Process is created,
	// and never changed afterward.
	// This is a pointer to a separate memory allocation
	// so that we can use runtime.AddCleanup.
	handle *processHandle

	// cleanup is used to clean up the process handle.
	cleanup runtime.Cleanup
}

// processHandle holds an operating system handle to a process.
// This is only used on systems that support that concept,
// currently Linux and Windows.
// This maintains a reference count to the handle,
// and closes the handle when the reference drops to zero.
type processHandle struct {
	// The actual handle. This field should not be used directly.
	// Instead, use the acquire and release methods.
	//
	// On Windows this is a handle returned by OpenProcess.
	// On Linux this is a pidfd.
	handle uintptr

	// Number of active references. When this drops to zero
	// the handle is closed.
	refs atomic.Int32
}

// acquire adds a reference and returns the handle.
// The bool result reports whether acquire succeeded;
// it fails if the handle is already closed.
// Every successful call to acquire should be paired with a call to release.
func (ph *processHandle) acquire() (uintptr, bool) {
	for {
		refs := ph.refs.Load()
		if refs < 0 {
			panic("internal error: negative process handle reference count")
		}
		if refs == 0 {
			return 0, false
		}
		if ph.refs.CompareAndSwap(refs, refs+1) {
			return ph.handle, true
		}
	}
}

// release releases a reference to the handle.
func (ph *processHandle) release() {
	for {
		refs := ph.refs.Load()
		if refs <= 0 {
			panic("internal error: too many releases of process handle")
		}
		if ph.refs.CompareAndSwap(refs, refs-1) {
			if refs == 1 {
				ph.closeHandle()
			}
			return
		}
	}
}

// newPIDProcess returns a [Process] for the given PID.
func newPIDProcess(pid int) *Process {
	p := &Process{
		Pid: pid,
	}
	return p
}

// newHandleProcess returns a [Process] with the given PID and handle.
func newHandleProcess(pid int, handle uintptr) *Process {
	ph := &processHandle{
		handle: handle,
	}

	// Start the reference count as 1,
	// meaning the reference from the returned Process.
	ph.refs.Store(1)

	p := &Process{
		Pid:    pid,
		handle: ph,
	}

	p.cleanup = runtime.AddCleanup(p, (*processHandle).release, ph)

	return p
}

// newDoneProcess returns a [Process] for the given PID
// that is already marked as done. This is used on Unix systems
// if the process is known to not exist.
func newDoneProcess(pid int) *Process {
	p := &Process{
		Pid: pid,
	}
	p.state.Store(uint32(statusDone)) // No persistent reference, as there is no handle.
	return p
}

// handleTransientAcquire returns the process handle or,
// if the process is not ready, the current status.
func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
	if p.handle == nil {
		panic("handleTransientAcquire called in invalid mode")
	}

	status := processStatus(p.state.Load())
	if status != statusOK {
		return 0, status
	}
	h, ok := p.handle.acquire()
	if ok {
		return h, statusOK
	}

	// This case means that the handle has been closed.
	// We always set the status to non-zero before closing the handle.
	// If we get here the status must have been set non-zero after
	// we just checked it above.
	status = processStatus(p.state.Load())
	if status == statusOK {
		panic("inconsistent process status")
	}
	return 0, status
}

// handleTransientRelease releases a handle returned by handleTransientAcquire.
func (p *Process) handleTransientRelease() {
	if p.handle == nil {
		panic("handleTransientRelease called in invalid mode")
	}
	p.handle.release()
}

// pidStatus returns the current process status.
func (p *Process) pidStatus() processStatus {
	if p.handle != nil {
		panic("pidStatus called in invalid mode")
	}

	return processStatus(p.state.Load())
}

// ProcAttr holds the attributes that will be applied to a new process
// started by StartProcess.
type ProcAttr struct {
	// If Dir is non-empty, the child changes into the directory before
	// creating the process.
	Dir string
	// If Env is non-nil, it gives the environment variables for the
	// new process in the form returned by Environ.
	// If it is nil, the result of Environ will be used.
	Env []string
	// Files specifies the open files inherited by the new process. The
	// first three entries correspond to standard input, standard output, and
	// standard error. An implementation may support additional entries,
	// depending on the underlying operating system. A nil entry corresponds
	// to that file being closed when the process starts.
	// On Unix systems, StartProcess will change these File values
	// to blocking mode, which means that SetDeadline will stop working
	// and calling Close will not interrupt a Read or Write.
	Files []*File

	// Operating system-specific process creation attributes.
	// Note that setting this field means that your program
	// may not execute properly or even compile on some
	// operating systems.
	Sys *syscall.SysProcAttr
}

// A Signal represents an operating system signal.
// The usual underlying implementation is operating system-dependent:
// on Unix it is syscall.Signal.
type Signal interface {
	String() string
	Signal() // to distinguish from other Stringers
}

// Getpid returns the process id of the caller.
func Getpid() int { return syscall.Getpid() }

// Getppid returns the process id of the caller's parent.
func Getppid() int { return syscall.Getppid() }

// FindProcess looks for a running process by its pid.
//
// The [Process] it returns can be used to obtain information
// about the underlying operating system process.
//
// On Unix systems, FindProcess always succeeds and returns a Process
// for the given pid, regardless of whether the process exists. To test whether
// the process actually exists, see whether p.Signal(syscall.Signal(0)) reports
// an error.
func FindProcess(pid int) (*Process, error) {
	return findProcess(pid)
}

// StartProcess starts a new process with the program, arguments and attributes
// specified by name, argv and attr. The argv slice will become [os.Args] in the
// new process, so it normally starts with the program name.
//
// If the calling goroutine has locked the operating system thread
// with [runtime.LockOSThread] and modified any inheritable OS-level
// thread state (for example, Linux or Plan 9 name spaces), the new
// process will inherit the caller's thread state.
//
// StartProcess is a low-level interface. The [os/exec] package provides
// higher-level interfaces.
//
// If there is an error, it will be of type [*PathError].
func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
	testlog.Open(name)
	return startProcess(name, argv, attr)
}

// Release releases any resources associated with the [Process] p,
// rendering it unusable in the future.
// Release only needs to be called if [Process.Wait] is not.
func (p *Process) Release() error {
	// Unfortunately, for historical reasons, on systems other
	// than Windows, Release sets the Pid field to -1.
	// This causes the race detector to report a problem
	// on concurrent calls to Release, but we can't change it now.
	if runtime.GOOS != "windows" {
		p.Pid = -1
	}

	oldStatus := p.doRelease(statusReleased)

	// For backward compatibility, on Windows only,
	// we return EINVAL on a second call to Release.
	if runtime.GOOS == "windows" {
		if oldStatus == statusReleased {
			return syscall.EINVAL
		}
	}

	return nil
}

// doRelease releases a [Process], setting the status to newStatus.
// If the previous status is not statusOK, this does nothing.
// It returns the previous status.
func (p *Process) doRelease(newStatus processStatus) processStatus {
	for {
		state := p.state.Load()
		oldStatus := processStatus(state)
		if oldStatus != statusOK {
			return oldStatus
		}

		if !p.state.CompareAndSwap(state, uint32(newStatus)) {
			continue
		}

		// We have successfully released the Process.
		// If it has a handle, release the reference we
		// created in newHandleProcess.
		if p.handle != nil {
			// No need for more cleanup.
			// We must stop the cleanup before calling release;
			// otherwise the cleanup might run concurrently
			// with the release, which would cause the reference
			// counts to be invalid, causing a panic.
			p.cleanup.Stop()

			p.handle.release()
		}

		return statusOK
	}
}

// Kill causes the [Process] to exit immediately. Kill does not wait until
// the Process has actually exited. This only kills the Process itself,
// not any other processes it may have started.
func (p *Process) Kill() error {
	return p.kill()
}

// Wait waits for the [Process] to exit, and then returns a
// ProcessState describing its status and an error, if any.
// Wait releases any resources associated with the Process.
// On most operating systems, the Process must be a child
// of the current process or an error will be returned.
func (p *Process) Wait() (*ProcessState, error) {
	return p.wait()
}

// Signal sends a signal to the [Process].
// Sending [Interrupt] on Windows is not implemented.
func (p *Process) Signal(sig Signal) error {
	return p.signal(sig)
}

// WithHandle calls a supplied function f with a valid process handle
// as an argument. The handle is guaranteed to refer to process p
// until f returns, even if p terminates. This function cannot be used
// after [Process.Release] or [Process.Wait].
//
// If process handles are not supported or a handle is not available,
// it returns [ErrNoHandle]. Currently, process handles are supported
// on Linux 5.4 or later (pidfd) and Windows.
func (p *Process) WithHandle(f func(handle uintptr)) error {
	return p.withHandle(f)
}

// UserTime returns the user CPU time of the exited process and its children.
func (p *ProcessState) UserTime() time.Duration {
	return p.userTime()
}

// SystemTime returns the system CPU time of the exited process and its children.
func (p *ProcessState) SystemTime() time.Duration {
	return p.systemTime()
}

// Exited reports whether the program has exited.
// On Unix systems this reports true if the program exited due to calling exit,
// but false if the program terminated due to a signal.
func (p *ProcessState) Exited() bool {
	return p.exited()
}

// Success reports whether the program exited successfully,
// such as with exit status 0 on Unix.
func (p *ProcessState) Success() bool {
	return p.success()
}

// Sys returns system-dependent exit information about
// the process. Convert it to the appropriate underlying
// type, such as [syscall.WaitStatus] on Unix, to access its contents.
func (p *ProcessState) Sys() any {
	return p.sys()
}

// SysUsage returns system-dependent resource usage information about
// the exited process. Convert it to the appropriate underlying
// type, such as [*syscall.Rusage] on Unix, to access its contents.
// (On Unix, *syscall.Rusage matches struct rusage as defined in the
// getrusage(2) manual page.)
func (p *ProcessState) SysUsage() any {
	return p.sysUsage()
}
