// 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.

// The exec package runs external commands.
package exec

import (
	"os"
	"strings"
)

// Arguments to Run.
const (
	DevNull = iota
	PassThrough
	Pipe
	MergeWithStdout
)

// A Cmd represents a running command.
// Stdin, Stdout, and Stderr are Files representing pipes
// connected to the running command's standard input, output, and error,
// or else nil, depending on the arguments to Run.
// Pid is the running command's operating system process ID.
type Cmd struct {
	Stdin  *os.File
	Stdout *os.File
	Stderr *os.File
	Pid    int
}

// Given mode (DevNull, etc), return file for child
// and file to record in Cmd structure.
func modeToFiles(mode, fd int) (*os.File, *os.File, os.Error) {
	switch mode {
	case DevNull:
		rw := os.O_WRONLY
		if fd == 0 {
			rw = os.O_RDONLY
		}
		f, err := os.Open(os.DevNull, rw, 0)
		return f, nil, err
	case PassThrough:
		switch fd {
		case 0:
			return os.Stdin, nil, nil
		case 1:
			return os.Stdout, nil, nil
		case 2:
			return os.Stderr, nil, nil
		}
	case Pipe:
		r, w, err := os.Pipe()
		if err != nil {
			return nil, nil, err
		}
		if fd == 0 {
			return r, w, nil
		}
		return w, r, nil
	}
	return nil, nil, os.EINVAL
}

// Run starts the named binary running with
// arguments argv and environment envv.
// It returns a pointer to a new Cmd representing
// the command or an error.
//
// The parameters stdin, stdout, and stderr
// specify how to handle standard input, output, and error.
// The choices are DevNull (connect to /dev/null),
// PassThrough (connect to the current process's standard stream),
// Pipe (connect to an operating system pipe), and
// MergeWithStdout (only for standard error; use the same
// file descriptor as was used for standard output).
// If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr)
// of the returned Cmd is the other end of the pipe.
// Otherwise the field in Cmd is nil.
func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (p *Cmd, err os.Error) {
	p = new(Cmd)
	var fd [3]*os.File

	if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil {
		goto Error
	}
	if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil {
		goto Error
	}
	if stderr == MergeWithStdout {
		fd[2] = fd[1]
	} else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil {
		goto Error
	}

	// Run command.
	p.Pid, err = os.ForkExec(name, argv, envv, dir, fd[0:])
	if err != nil {
		goto Error
	}
	if fd[0] != os.Stdin {
		fd[0].Close()
	}
	if fd[1] != os.Stdout {
		fd[1].Close()
	}
	if fd[2] != os.Stderr && fd[2] != fd[1] {
		fd[2].Close()
	}
	return p, nil

Error:
	if fd[0] != os.Stdin && fd[0] != nil {
		fd[0].Close()
	}
	if fd[1] != os.Stdout && fd[1] != nil {
		fd[1].Close()
	}
	if fd[2] != os.Stderr && fd[2] != nil && fd[2] != fd[1] {
		fd[2].Close()
	}
	if p.Stdin != nil {
		p.Stdin.Close()
	}
	if p.Stdout != nil {
		p.Stdout.Close()
	}
	if p.Stderr != nil {
		p.Stderr.Close()
	}
	return nil, err
}

// Wait waits for the running command p,
// returning the Waitmsg returned by os.Wait and an error.
// The options are passed through to os.Wait.
// Setting options to 0 waits for p to exit;
// other options cause Wait to return for other
// process events; see package os for details.
func (p *Cmd) Wait(options int) (*os.Waitmsg, os.Error) {
	if p.Pid <= 0 {
		return nil, os.ErrorString("exec: invalid use of Cmd.Wait")
	}
	w, err := os.Wait(p.Pid, options)
	if w != nil && (w.Exited() || w.Signaled()) {
		p.Pid = -1
	}
	return w, err
}

// Close waits for the running command p to exit,
// if it hasn't already, and then closes the non-nil file descriptors
// p.Stdin, p.Stdout, and p.Stderr.
func (p *Cmd) Close() os.Error {
	if p.Pid > 0 {
		// Loop on interrupt, but
		// ignore other errors -- maybe
		// caller has already waited for pid.
		_, err := p.Wait(0)
		for err == os.EINTR {
			_, err = p.Wait(0)
		}
	}

	// Close the FDs that are still open.
	var err os.Error
	if p.Stdin != nil && p.Stdin.Fd() >= 0 {
		if err1 := p.Stdin.Close(); err1 != nil {
			err = err1
		}
	}
	if p.Stdout != nil && p.Stdout.Fd() >= 0 {
		if err1 := p.Stdout.Close(); err1 != nil && err != nil {
			err = err1
		}
	}
	if p.Stderr != nil && p.Stderr != p.Stdout && p.Stderr.Fd() >= 0 {
		if err1 := p.Stderr.Close(); err1 != nil && err != nil {
			err = err1
		}
	}
	return err
}

func canExec(file string) bool {
	d, err := os.Stat(file)
	if err != nil {
		return false
	}
	return d.IsRegular() && d.Permission()&0111 != 0
}

// LookPath searches for an executable binary named file
// in the directories named by the PATH environment variable.
// If file contains a slash, it is tried directly and the PATH is not consulted.
//
// TODO(rsc): Does LookPath belong in os instead?
func LookPath(file string) (string, os.Error) {
	// NOTE(rsc): I wish we could use the Plan 9 behavior here
	// (only bypass the path if file begins with / or ./ or ../)
	// but that would not match all the Unix shells.

	if strings.Index(file, "/") >= 0 {
		if canExec(file) {
			return file, nil
		}
		return "", os.ENOENT
	}
	pathenv := os.Getenv("PATH")
	for _, dir := range strings.Split(pathenv, ":", -1) {
		if dir == "" {
			// Unix shell semantics: path element "" means "."
			dir = "."
		}
		if canExec(dir + "/" + file) {
			return dir + "/" + file, nil
		}
	}
	return "", os.ENOENT
}
