// Copyright 2015 The Vanadium 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 runutil

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sync"
	"syscall"
	"time"

	"v.io/x/lib/cmdline"
	"v.io/x/lib/envvar"
)

// Sequence provides for convenient chaining of multiple calls to its
// methods to avoid repeated tests for error returns. The usage is:
//
// err := s.Run("echo", "a").Run("echo", "b").Done()
//
// The first method to encounter an error short circuits any following
// methods and the result of that first error is returned by the
// Done method or any of the other 'terminating methods' (see below).
// Sequence is not thread safe. It also good practice to use a new
// instance of a Sequence in defer's.
//
// Unless directed to specific stdout and stderr io.Writers using Capture(),
// the stdout and stderr output from the command is discarded, unless an error
// is encountered, in which case the output from the command that failed (both
// stdout and stderr) is written to the stderr io.Writer specified via
// NewSequence. In addition, in verbose mode, command execution logging
// is written to the stdout an stderr io.Writers configured via NewSequence.
//
// Modifier methods are provided that influence the behaviour of the
// next invocation of the Run method to set timeouts (Timed), to
// capture output (Capture), input (Read) and to set the environment (Env).
// For example, the following will result in a timeout error.
//
// err := s.Timeout(time.Second).Run("sleep","10").Done()
// err := s.Timeout(time.Second).Last("sleep","10")
//
// A sequence of commands must be terminated with a call to a 'terminating'
// method. The simplest are the Done or Last methods used in the examples above,
// but there are other methods which typically return results in addition to
// error, such as ReadFile(filename string) ([]byte, error). Here the usage
// would be:
//
// o.Stdout, _ = os.Create("foo")
// data, err := s.Capture(o, nil).Run("echo","b").ReadFile("foo")
// // data == "b"
//
// Note that terminating functions, even those that take an action, may
// return an error generated by a previous method.
//
// In addition to Run which will always run a command as a subprocess,
// the Call method will invoke a function. Note that Capture and Timeout
// do not affect such calls.
//
// Errors returned by Sequence augment those returned by the underlying
// packages with details of the exact call that generated those errors.
// This means that it is not possible to test directly for errors from
// those packages. The GetOriginalError function can be used to obtain
// the error from the underlying package, or the IsTimeout, IsNotExists etc
// functions can be used on the wrapped error. The ExitCode method
// is also provided to convert to the exit codes expected by the
// v.io/x/lib/cmdline package which is often used in conjunction with
// Sequence.
type Sequence struct {
	// NOTE: we use a struct as the return value of all
	// Sequence methods to ensure that code of the form:
	// if err := s.WriteFile(); err != nil {...}
	// does not compile.
	*sequence
}

type sequence struct {
	r                            *executor
	err                          error
	caller                       string
	stdout, stderr               io.Writer
	stdin                        io.Reader
	reading                      bool
	env                          map[string]string
	opts                         *opts
	defaultStdin                 io.Reader
	defaultStdout, defaultStderr io.Writer
	dirs                         []string
	verbosity                    *bool
	dryRun                       *bool
	cmdDir                       string
	timeout                      time.Duration
	serializedWriterLock         sync.Mutex
}

// NewSequence creates an instance of Sequence with default values for its
// environment, stdin, stderr, stdout and other supported options.
// If the environment parameter is nil or empty then the current value of
// os.Environ() will be used instead.
func NewSequence(env map[string]string, stdin io.Reader, stdout, stderr io.Writer, color, dryRun, verbose bool) Sequence {
	if len(env) == 0 {
		env = envvar.SliceToMap(os.Environ())
	}
	s := Sequence{
		&sequence{
			r:            newExecutor(env, stdin, stdout, stderr, color, dryRun, verbose),
			defaultStdin: stdin,
		},
	}
	s.defaultStdout, s.defaultStderr = s.serializeWriter(stdout), s.serializeWriter(stderr)
	return s
}

// RunOpts returns the values of dryRun and verbose that were used to
// create this sequence.
func (s Sequence) RunOpts() (dryRun bool, verbose bool) {
	opts := s.getOpts()
	return opts.dryRun, opts.verbose
}

// Capture arranges for the next call to Run or Last to write its stdout and
// stderr output to the supplied io.Writers. This will be cleared and not used
// for any calls to Run or Last beyond the next one. Specifying nil for
// a writer will result in using the the corresponding io.Writer supplied
// to NewSequence. ioutil.Discard should be used to discard output.
func (s Sequence) Capture(stdout, stderr io.Writer) Sequence {
	if s.err != nil {
		return s
	}
	s.stdout, s.stderr = stdout, stderr
	return s
}

// Read arranges for the next call to Run or Last to read from the supplied
// io.Reader. This will be cleared and not used for any calls to Run or Last
// beyond the next one. Specifying nil will result in reading from os.DevNull.
func (s Sequence) Read(stdin io.Reader) Sequence {
	if s.err != nil {
		return s
	}
	s.reading = true
	s.stdin = stdin
	return s
}

// SetEnv arranges for the next call to Run, Call, Start or Last to use the supplied
// environment variables. These will be cleared and not used for any calls
// to Run, Call or Last beyond the next one.
func (s Sequence) SetEnv(env map[string]string) Sequence {
	if s.err != nil {
		return s
	}
	s.env = env
	return s
}

// Env arranges for the next call to Run, Call, Start or Last to use
// the result of merging the supplied environment variables with those
// specified when the sequence was created or with those set by the most
// recent call to the Env method. These will be cleared and not used
// for any calls to Run, Call or Last beyond the next one.
func (s Sequence) Env(env map[string]string) Sequence {
	if s.err != nil {
		return s
	}
	if s.env != nil {
		s.env = envvar.MergeMaps(s.env, env)
	} else {
		e := s.getOpts().env
		s.env = envvar.MergeMaps(e, env)
	}
	return s
}

// Verbosity arranges for the next call to Run, Call, Start or Last to use the
// specified verbosity. This will be cleared and not used for any calls
// to Run, Call or Last beyond the next one.
func (s Sequence) Verbose(verbosity bool) Sequence {
	if s.err != nil {
		return s
	}
	s.verbosity = &verbosity
	return s
}

// Dir sets the working directory for the next subprocess that is created
// via Run, Call, Start or Last to the supplied parameter. This is the only
// way to safely set the working directory of a command when multiple threads
// are used.
func (s Sequence) Dir(dir string) Sequence {
	if s.err != nil {
		return s
	}
	s.cmdDir = dir
	return s
}

// DryRun arranges for the next call to Run, Call, Start or Last to use the
// specified dry run value. This will be cleared and not used for any calls
// to Run, Call or Last beyond the next one.
func (s Sequence) DryRun(dryRun bool) Sequence {
	if s.err != nil {
		return s
	}
	s.dryRun = &dryRun
	return s
}

// internal getOpts that doesn't override stdin, stdout, stderr
func (s Sequence) getOpts() opts {
	var opts opts
	if s.opts != nil {
		opts = *s.opts
	} else {
		opts = s.r.opts
	}
	return opts
}

// Timeout arranges for the next call to Run, Start or Last to be subject to the
// specified timeout. The timeout will be cleared and not used any calls to Run
// or Last beyond the next one. It has no effect for calls to Call.
func (s Sequence) Timeout(timeout time.Duration) Sequence {
	if s.err != nil {
		return s
	}
	s.timeout = timeout
	return s
}

func (s Sequence) setOpts(opts opts) {
	s.opts = &opts
}

type wrappedError struct {
	oe, we error
}

func (ie *wrappedError) Error() string {
	return ie.we.Error()
}

// Error returns the error, if any, stored in the Sequence.
func (s Sequence) Error() error {
	if s.err != nil && len(s.caller) > 0 {
		return &wrappedError{oe: s.err, we: fmt.Errorf("%s: %v", s.caller, s.err)}
	}
	return s.err
}

// TranslateExitCode translates errors from the "os/exec" package that
// contain exit codes into cmdline.ErrExitCode errors.
func TranslateExitCode(err error) error {
	return translateExitCode(GetOriginalError(err))
}

func translateExitCode(err error) error {
	if exit, ok := err.(*exec.ExitError); ok {
		if wait, ok := exit.Sys().(syscall.WaitStatus); ok {
			if status := wait.ExitStatus(); wait.Exited() && status != 0 {
				return cmdline.ErrExitCode(status)
			}
		}
	}
	return err
}

// GetOriginalError gets the original error wrapped in the supplied err.
// If the given err has not been wrapped by Sequence, then the supplied error
// is returned.
func GetOriginalError(err error) error {
	if we, ok := err.(*wrappedError); ok {
		return we.oe
	}
	return err
}

// IsExist returns a boolean indicating whether the error is known
// to report that a file or directory already exists.
func IsExist(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsExist(we.oe)
	}
	return os.IsExist(err)
}

// IsNotExist returns a boolean indicating whether the error is known
// to report that a file or directory does not exist.
func IsNotExist(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsNotExist(we.oe)
	}
	return os.IsNotExist(err)
}

// IsPermission returns a boolean indicating whether the error is known
// to report that permission is denied.
func IsPermission(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return os.IsPermission(we.oe)
	}
	return os.IsPermission(err)
}

// IsTimeout returns a boolean indicating whether the error is a result of
// a timeout.
func IsTimeout(err error) bool {
	if we, ok := err.(*wrappedError); ok {
		return we.oe == commandTimedOutErr
	}
	return err == commandTimedOutErr
}

func fmtError(depth int, err error, detail string) string {
	_, file, line, _ := runtime.Caller(depth + 1)
	return fmt.Sprintf("%s:%d: %s", filepath.Base(file), line, detail)
}

func (s Sequence) setError(err error, detail string) {
	if err == nil || s.err != nil {
		return
	}
	s.err = err
	s.caller = fmtError(2, err, detail)
}

// reset all state except s.err
func (s Sequence) reset() {
	s.stdin, s.stdout, s.stderr, s.env = nil, nil, nil, nil
	s.opts, s.verbosity, s.dryRun = nil, nil, nil
	s.cmdDir = ""
	s.reading = false
	s.timeout = 0
}

func cleanup(p1, p2 *io.PipeWriter, stdinCh, stderrCh chan error) error {
	p1.Close()
	p2.Close()
	if stdinCh != nil {
		if err := <-stdinCh; err != nil {
			return err
		}
	}
	if stderrCh != nil {
		if err := <-stderrCh; err != nil {
			return err
		}
	}
	return nil
}

func useIfNotNil(a, b io.Writer) io.Writer {
	if a != nil {
		return a
	}
	return b
}

func writeOutput(logdir bool, from string, to io.Writer) {
	if fi, err := os.Open(from); err == nil {
		io.Copy(to, fi)
		fi.Close()
	}
	if !logdir {
		return
	}
	if wd, err := os.Getwd(); err == nil {
		fmt.Fprintf(to, "Current Directory: %v\n", wd)
	}
}

type sharedLockWriter struct {
	mu *sync.Mutex
	f  io.Writer
}

func (lw *sharedLockWriter) Write(d []byte) (int, error) {
	lw.mu.Lock()
	defer lw.mu.Unlock()
	return lw.f.Write(d)
}

func (s Sequence) serializeWriter(a io.Writer) io.Writer {
	if a != nil {
		return &sharedLockWriter{&s.serializedWriterLock, a}
	}
	return nil
}

// isWriterTTY returns whether the io.Writer w is an os.File pointing at a tty.
func isWriterTTY(w io.Writer) (isTTY bool) {
	_, isOsFile := w.(*os.File)
	if isOsFile {
		stat, _ := os.Stdin.Stat()
		isTTY = (stat.Mode() & (os.ModeDevice | os.ModeCharDevice)) == (os.ModeDevice | os.ModeCharDevice)
	}
	return isTTY
}

func (s Sequence) initAndDefer(h *Handle) func() {
	if s.stdout == nil && s.stderr == nil {
		fout, err := ioutil.TempFile("", "seq")
		if err != nil {
			return func() {}
		}
		opts := s.getOpts()
		opts.stdout, opts.stderr = s.serializeWriter(fout), s.serializeWriter(fout)
		if len(s.env) > 0 {
			opts.env = s.env
		}
		if s.reading {
			opts.stdin = s.stdin
		}
		if s.verbosity != nil {
			opts.verbose = *s.verbosity
		}
		if s.dryRun != nil {
			opts.dryRun = *s.dryRun
		}
		opts.dir = s.cmdDir
		s.setOpts(opts)
		if h != nil {
			return func() {
				h.stderr = useIfNotNil(s.defaultStderr, os.Stderr)
				h.filename = fout.Name()
				h.doneErr = nil
				fout.Close()
			}
		}
		return func() {
			filename := fout.Name()
			fout.Close()
			defer func() { os.Remove(filename); s.opts = nil }()
			if s.err != nil {
				writeOutput(true, filename, useIfNotNil(s.defaultStderr, os.Stderr))
			}
			if opts.verbose && s.defaultStderr != s.defaultStdout {
				writeOutput(false, filename, useIfNotNil(s.defaultStdout, os.Stdout))
			}
		}
	}
	opts := s.getOpts()
	rStdout, wStdout := io.Pipe()
	rStderr, wStderr := io.Pipe()
	// If the requested stdout/stderr is a raw os.File pointing at a tty,
	// use that directly.  This allows the invocation of tools
	// like editors, which expect stdout/stderr to be ttys.
	if isWriterTTY(s.stdout) {
		opts.stdout = s.stdout
	} else {
		opts.stdout = wStdout
	}
	if isWriterTTY(s.stderr) {
		opts.stderr = s.stderr
	} else {
		opts.stderr = wStderr
	}
	if len(s.env) > 0 {
		opts.env = s.env
	}
	if s.reading {
		opts.stdin = s.stdin
	}
	var stdinCh, stderrCh chan error
	stdout, stderr := s.serializeWriter(s.stdout), s.serializeWriter(s.stderr)
	if stdout != nil {
		stdinCh = make(chan error)
		go copy(stdout, rStdout, stdinCh)
	} else {
		opts.stdout = s.defaultStdout
	}
	if stderr != nil {
		stderrCh = make(chan error)
		go copy(stderr, rStderr, stderrCh)
	} else {
		opts.stderr = s.defaultStderr
	}
	if s.verbosity != nil {
		opts.verbose = *s.verbosity
	}
	if s.dryRun != nil {
		opts.dryRun = *s.dryRun
	}
	opts.dir = s.cmdDir
	s.setOpts(opts)
	if h != nil {
		return func() {
			h.filename = ""
			h.doneErr = cleanup(wStdout, wStderr, stdinCh, stderrCh)
		}
	}
	return func() {
		if err := cleanup(wStdout, wStderr, stdinCh, stderrCh); err != nil && s.err == nil {
			// If we haven't already encountered an error and we fail to
			// cleanup then record the error from the cleanup
			s.err = err
		}
		// reset does not affect s.err
		s.reset()
	}
}

func fmtStringArgs(args ...string) string {
	if len(args) == 0 {
		return ""
	}
	var out bytes.Buffer
	for _, a := range args {
		fmt.Fprintf(&out, ", %q", a)
	}
	return out.String()
}

// Run runs the given command as a subprocess.
func (s Sequence) Run(path string, args ...string) Sequence {
	if s.err != nil {
		return s
	}
	defer s.initAndDefer(nil)()
	s.setError(s.r.run(s.timeout, s.getOpts(), path, args...), fmt.Sprintf("Run(%q%s)", path, fmtStringArgs(args...)))
	return s
}

// Last runs the given command as a subprocess and returns an error
// immediately terminating the sequence, it is equivalent to
// calling s.Run(path, args...).Done().
func (s Sequence) Last(path string, args ...string) error {
	if s.err != nil {
		return s.Done()
	}
	defer s.Done()
	defer s.initAndDefer(nil)()
	s.setError(s.r.run(s.timeout, s.getOpts(), path, args...), fmt.Sprintf("Last(%q%s)", path, fmtStringArgs(args...)))
	return s.Error()
}

// Call runs the given function. Note that Capture and Timeout have no
// effect on invocations of Call, but Opts can control logging.
func (s Sequence) Call(fn func() error, format string, args ...interface{}) Sequence {
	if s.err != nil {
		return s
	}
	defer s.initAndDefer(nil)()
	s.setError(s.r.function(s.getOpts(), fn, format, args...), fmt.Sprintf(format, args...))
	return s
}

// Handle represents a command running in the background.
type Handle struct {
	stdout, stderr io.Writer
	doneErr        error
	filename       string
	deferFn        func()
	cmd            *exec.Cmd
}

// Kill terminates the currently running background process.
func (h *Handle) Kill() error {
	return h.cmd.Process.Kill()
}

// Pid returns the pid of the running process.
func (h *Handle) Pid() int {
	return h.cmd.Process.Pid
}

func (h *Handle) Signal(sig os.Signal) error {
	return h.cmd.Process.Signal(sig)
}

// Wait waits for the currently running background process to terminate.
func (h *Handle) Wait() error {
	err := h.cmd.Wait()
	h.deferFn()
	if len(h.filename) > 0 {
		if err != nil {
			writeOutput(true, h.filename, h.stderr)
		}
		os.Remove(h.filename)
		return err
	}
	return h.doneErr
}

// Start runs the given command as a subprocess in background and returns
// a handle that can be used to kill and/or wait for that background process.
// Start is a terminating function.
func (s Sequence) Start(path string, args ...string) (*Handle, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	h := &Handle{}
	h.deferFn = s.initAndDefer(h)
	cmd, err := s.r.start(s.timeout, s.getOpts(), path, args...)
	h.cmd = cmd
	s.setError(err, fmt.Sprintf("Start(%q%s)", path, fmtStringArgs(args...)))
	return h, s.Error()
}

// Output logs the given list of lines using the currently in effect verbosity
// as specified by Opts, or the default otherwise.
func (s Sequence) Output(output []string) Sequence {
	if s.err != nil {
		return s
	}
	opts := s.getOpts()
	if s.verbosity != nil {
		opts.verbose = *s.verbosity
	}
	s.r.output(opts, output)
	return s
}

// Fprintf calls fmt.Fprintf.
func (s Sequence) Fprintf(f io.Writer, format string, args ...interface{}) Sequence {
	if s.err != nil {
		return s
	}
	fmt.Fprintf(f, format, args...)
	return s
}

// Done returns the error stored in the Sequence and pops back to the first
// entry in the directory stack if Pushd has been called. Done is a terminating
// function. There is no need to ensure that Done is called before returning
// from a function that uses a sequence unless it is necessary to pop the
// stack.
func (s Sequence) Done() error {
	rerr := s.Error()
	s.err = nil
	s.caller = ""
	s.reset()
	if len(s.dirs) > 0 {
		cwd := s.dirs[0]
		s.dirs = nil
		err := s.r.alwaysRun(func() error {
			return os.Chdir(cwd)
		}, fmt.Sprintf("sequence done popd %q", cwd))
		if err != nil {
			detail := "Done: Chdir(" + cwd + ")"
			if rerr == nil {
				s.setError(err, detail)
			} else {
				// In the unlikely event that Chdir fails in addition to an
				// earlier error, we append an appropriate error message.
				s.err = fmt.Errorf("%v\n%v", rerr, fmtError(1, err, detail))
			}
			return s.Error()
		}
	}
	return rerr
}

// Pushd pushes the current directory onto a stack and changes directory
// to the specified one. Calling any terminating function will pop back
// to the first element in the stack on completion of that function.
func (s Sequence) Pushd(dir string) Sequence {
	cwd, err := os.Getwd()
	if err != nil {
		s.setError(err, "Pushd("+dir+"): os.Getwd")
		return s
	}
	s.dirs = append(s.dirs, cwd)
	err = s.r.alwaysRun(func() error {
		return os.Chdir(dir)
	}, fmt.Sprintf("pushd %q", dir))
	s.setError(err, "Pushd("+dir+")")
	return s
}

// Popd popds the last directory from the directory stack and chdir's to it.
// Calling any termination function will pop back to the first element in
// the stack on completion of that function.
func (s Sequence) Popd() Sequence {
	if s.err != nil {
		return s
	}
	if len(s.dirs) == 0 {
		s.setError(fmt.Errorf("directory stack is empty"), "Popd()")
		return s
	}
	last := s.dirs[len(s.dirs)-1]
	s.dirs = s.dirs[:len(s.dirs)-1]
	err := s.r.alwaysRun(func() error {
		return os.Chdir(last)
	}, fmt.Sprintf("popd %q", last))
	s.setError(err, "Popd() -> "+last)
	return s
}

// Chdir is a wrapper around os.Chdir that handles options such as
// "verbose" or "dry run".
func (s Sequence) Chdir(dir string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.alwaysRun(func() error {
		return os.Chdir(dir)
	}, fmt.Sprintf("cd %q", dir))
	s.setError(err, "Chdir("+dir+")")
	return s

}

// Chmod is a wrapper around os.Chmod that handles options such as
// "verbose" or "dry run".
func (s Sequence) Chmod(dir string, mode os.FileMode) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error { return os.Chmod(dir, mode) }, fmt.Sprintf("chmod %v %q", mode, dir))
	s.setError(err, fmt.Sprintf("Chmod(%s, %s)", dir, mode))
	return s

}

// MkdirAll is a wrapper around os.MkdirAll that handles options such
// as "verbose" or "dry run".
func (s Sequence) MkdirAll(dir string, mode os.FileMode) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error { return os.MkdirAll(dir, mode) }, fmt.Sprintf("mkdir -p %q", dir))
	s.setError(err, fmt.Sprintf("MkdirAll(%s, %s)", dir, mode))
	return s
}

// RemoveAll is a wrapper around os.RemoveAll that handles options
// such as "verbose" or "dry run".
func (s Sequence) RemoveAll(dir string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error { return os.RemoveAll(dir) }, fmt.Sprintf("rm -rf %q", dir))
	s.setError(err, fmt.Sprintf("RemoveAll(%s)", dir))
	return s
}

// Remove is a wrapper around os.Remove that handles options
// such as "verbose" or "dry run".
func (s Sequence) Remove(file string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error { return os.Remove(file) }, fmt.Sprintf("rm %q", file))
	s.setError(err, fmt.Sprintf("Remove(%s)", file))
	return s
}

// Rename is a wrapper around os.Rename that handles options such as
// "verbose" or "dry run".
func (s Sequence) Rename(src, dst string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error {
		if err := os.Rename(src, dst); err != nil {
			// Check if the rename operation failed
			// because the source and destination are
			// located on different mount points.
			linkErr, ok := err.(*os.LinkError)
			if !ok {
				return err
			}
			errno, ok := linkErr.Err.(syscall.Errno)
			if !ok || errno != syscall.EXDEV {
				return err
			}
			// Fall back to a non-atomic rename.
			cmd := exec.Command("mv", src, dst)
			return cmd.Run()
		}
		return nil
	}, fmt.Sprintf("mv %q %q", src, dst))
	s.setError(err, fmt.Sprintf("Rename(%s, %s)", src, dst))
	return s

}

// Symlink is a wrapper around os.Symlink that handles options such as
// "verbose" or "dry run".
func (s Sequence) Symlink(src, dst string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error { return os.Symlink(src, dst) }, fmt.Sprintf("ln -s %q %q", src, dst))
	s.setError(err, fmt.Sprintf("Symlink(%s, %s)", src, dst))
	return s
}

// Open is a wrapper around os.Open that handles options such as
// "verbose" or "dry run". Open is a terminating function.
func (s Sequence) Open(name string) (f *os.File, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.call(func() error {
		f, err = os.Open(name)
		return err
	}, fmt.Sprintf("open %q", name))
	s.setError(err, fmt.Sprintf("Open(%s)", name))
	err = s.Done()
	return
}

// OpenFile is a wrapper around os.OpenFile that handles options such as
// "verbose" or "dry run". OpenFile is a terminating function.
func (s Sequence) OpenFile(name string, flag int, perm os.FileMode) (f *os.File, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.call(func() error {
		f, err = os.OpenFile(name, flag, perm)
		return err
	}, fmt.Sprintf("open file %q", name))
	s.setError(err, fmt.Sprintf("OpenFile(%s, %s, %s)", name, flag, perm))
	err = s.Done()
	return
}

// Create is a wrapper around os.Create that handles options such as "verbose"
// or "dry run". Create is a terminating function.
func (s Sequence) Create(name string) (f *os.File, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.call(func() error {
		var err error
		f, err = os.Create(name)
		return err
	}, fmt.Sprintf("create %q", name))
	s.setError(err, fmt.Sprintf("Create(%s)", name))
	err = s.Done()
	return
}

// ReadDir is a wrapper around ioutil.ReadDir that handles options
// such as "verbose" or "dry run". ReadDir is a terminating function.
func (s Sequence) ReadDir(dirname string) (fi []os.FileInfo, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.alwaysRun(func() error {
		fi, err = ioutil.ReadDir(dirname)
		return err
	}, fmt.Sprintf("ls %q", dirname))
	s.setError(err, fmt.Sprintf("ReadDir(%s)", dirname))
	err = s.Done()
	return
}

// ReadFile is a wrapper around ioutil.ReadFile that handles options
// such as "verbose" or "dry run". ReadFile is a terminating function.
func (s Sequence) ReadFile(filename string) (bytes []byte, err error) {

	if s.err != nil {
		return nil, s.Done()
	}
	s.r.alwaysRun(func() error {
		bytes, err = ioutil.ReadFile(filename)
		return err
	}, fmt.Sprintf("read %q", filename))
	s.setError(err, fmt.Sprintf("ReadFile(%s)", filename))
	err = s.Done()
	return
}

// WriteFile is a wrapper around ioutil.WriteFile that handles options
// such as "verbose" or "dry run".
func (s Sequence) WriteFile(filename string, data []byte, perm os.FileMode) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(func() error {
		return ioutil.WriteFile(filename, data, perm)
	}, fmt.Sprintf("write %q", filename))
	s.setError(err, fmt.Sprintf("WriteFile(%s, %.10s,  %s)", filename, data, perm))
	return s
}

// Copy is a wrapper around io.Copy that handles options such as "verbose" or
// "dry run". Copy is a terminating function.
func (s Sequence) Copy(dst io.Writer, src io.Reader) (n int64, err error) {
	if s.err != nil {
		return 0, s.Done()
	}
	s.r.call(func() error {
		n, err = io.Copy(dst, src)
		return err
	}, "io.copy")
	s.setError(err, fmt.Sprintf("Copy(%s, %s)", dst, src))
	err = s.Done()
	return
}

// Stat is a wrapper around os.Stat that handles options such as
// "verbose" or "dry run". Stat is a terminating function.
func (s Sequence) Stat(name string) (fi os.FileInfo, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.alwaysRun(func() error {
		fi, err = os.Stat(name)
		return err
	}, fmt.Sprintf("stat %q", name))
	s.setError(err, fmt.Sprintf("Stat(%s)", name))
	err = s.Done()
	return
}

// Lstat is a wrapper around os.Lstat that handles options such as
// "verbose" or "dry run". Lstat is a terminating function.
func (s Sequence) Lstat(name string) (fi os.FileInfo, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	s.r.alwaysRun(func() error {
		fi, err = os.Lstat(name)
		return err
	}, fmt.Sprintf("lstat %q", name))
	s.setError(err, fmt.Sprintf("Lstat(%s)", name))
	err = s.Done()
	return
}

// Readlink is a wrapper around os.Readlink that handles options such as
// "verbose" or "dry run". Lstat is a terminating function.
func (s Sequence) Readlink(name string) (link string, err error) {
	if s.err != nil {
		return "", s.Done()
	}
	s.r.alwaysRun(func() error {
		link, err = os.Readlink(name)
		return err
	}, fmt.Sprintf("readlink %q", name))
	s.setError(err, fmt.Sprintf("Readlink(%s)", name))
	err = s.Done()
	return
}

// TempDir is a wrapper around ioutil.TempDir that handles options
// such as "verbose" or "dry run". TempDir is a terminating function.
func (s Sequence) TempDir(dir, prefix string) (tmpDir string, err error) {
	if s.err != nil {
		return "", s.Done()
	}
	if dir == "" {
		dir = os.Getenv("TMPDIR")
	}
	tmpDir = filepath.Join(dir, prefix+"XXXXXX")
	s.r.call(func() error {
		tmpDir, err = ioutil.TempDir(dir, prefix)
		return err
	}, fmt.Sprintf("mkdir -p %q", tmpDir))
	s.setError(err, fmt.Sprintf("TempDir(%s,%s)", dir, prefix))
	err = s.Done()
	return
}

// TempFile is a wrapper around ioutil.TempFile that handles options
// such as "verbose" or "dry run".
func (s Sequence) TempFile(dir, prefix string) (f *os.File, err error) {
	if s.err != nil {
		return nil, s.Done()
	}
	if dir == "" {
		dir = os.Getenv("TMPDIR")
	}
	s.r.call(func() error {
		f, err = ioutil.TempFile(dir, prefix)
		return err
	}, fmt.Sprintf("tempFile %q %q", dir, prefix))
	s.setError(err, fmt.Sprintf("TempFile(%s,%s)", dir, prefix))
	err = s.Done()
	return
}

// IsDir is a wrapper around os.Stat with appropriate logging that
// returns true of dirname exists and is a directory.
// IsDir is a terminating function.
func (s Sequence) IsDir(dirname string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	var fileInfo os.FileInfo
	var err error
	err = s.r.alwaysRun(func() error {
		fileInfo, err = os.Stat(dirname)
		return err
	}, fmt.Sprintf("isdir %q", dirname))
	if IsNotExist(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	s.setError(err, fmt.Sprintf("IsDir(%s)", dirname))
	return fileInfo.IsDir(), s.Done()
}

// IsFile is a wrapper around os.Stat with appropriate logging that
// returns true if file exists and is not a directory.
// IsFile is a terminating function.
func (s Sequence) IsFile(file string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	var fileInfo os.FileInfo
	var err error
	err = s.r.alwaysRun(func() error {
		fileInfo, err = os.Stat(file)
		return err
	}, fmt.Sprintf("isfile %q", file))
	if IsNotExist(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	s.setError(err, fmt.Sprintf("IsFile(%s)", file))
	return !fileInfo.IsDir(), s.Done()
}

// AssertDirExists asserts that the specified directory exists with appropriate
// logging.
func (s Sequence) AssertDirExists(dirname string) Sequence {
	if s.err != nil {
		return s
	}
	isdir, err := s.IsDir(dirname)
	if !isdir && err == nil {
		err = os.ErrNotExist
	}
	s.setError(err, fmt.Sprintf("AssertDirExists(%s)", dirname))
	return s
}

// AssertFileExists asserts that the specified file exists with appropriate
// logging.
func (s Sequence) AssertFileExists(file string) Sequence {
	if s.err != nil {
		return s
	}
	isfile, err := s.IsFile(file)
	if !isfile && err == nil {
		err = os.ErrNotExist
	}
	s.setError(err, fmt.Sprintf("AssertFileExists(%s)", file))
	return s
}

func copy(to io.Writer, from io.Reader, ch chan error) {
	_, err := io.Copy(to, from)
	ch <- err
}
