// 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"
	"strconv"
)

// 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.
// Process represents the underlying operating system process.
type Cmd struct {
	Stdin   *os.File
	Stdout  *os.File
	Stderr  *os.File
	Process *os.Process
}

// PathError records the name of a binary that was not
// found on the current $PATH.
type PathError struct {
	Name string
}

func (e *PathError) String() string {
	return "command " + strconv.Quote(e.Name) + " not found in $PATH"
}

// 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.
// If the dir argument is not empty, the child changes
// into the directory before executing the binary.
// It returns a pointer to a new Cmd representing
// the command or an error.
//
// The arguments 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 an argument 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) (c *Cmd, err os.Error) {
	c = new(Cmd)
	var fd [3]*os.File

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

	// Run command.
	c.Process, err = os.StartProcess(name, argv, &os.ProcAttr{Dir: dir, Files: fd[:], Env: envv})
	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 c, 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 c.Stdin != nil {
		c.Stdin.Close()
	}
	if c.Stdout != nil {
		c.Stdout.Close()
	}
	if c.Stderr != nil {
		c.Stderr.Close()
	}
	if c.Process != nil {
		c.Process.Release()
	}
	return nil, err
}

// Wait waits for the running command c,
// returning the Waitmsg returned when the process exits.
// The options are passed to the process's Wait method.
// Setting options to 0 waits for c to exit;
// other options cause Wait to return for other
// process events; see package os for details.
func (c *Cmd) Wait(options int) (*os.Waitmsg, os.Error) {
	if c.Process == nil {
		return nil, os.ErrorString("exec: invalid use of Cmd.Wait")
	}
	w, err := c.Process.Wait(options)
	if w != nil && (w.Exited() || w.Signaled()) {
		c.Process.Release()
		c.Process = nil
	}
	return w, err
}

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

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