// 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
	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, verbose bool) Sequence {
	if len(env) == 0 {
		env = envvar.SliceToMap(os.Environ())
	}
	s := Sequence{
		&sequence{
			r:            newExecutor(env, stdin, stdout, stderr, color, verbose),
			defaultStdin: stdin,
		},
	}
	s.defaultStdout, s.defaultStderr = s.serializeWriter(stdout), s.serializeWriter(stderr)
	return s
}

// RunOpts returns the value of verbose that was used to
// create this sequence.
func (s Sequence) RunOpts() (verbose bool) {
	opts := s.getOpts()
	return 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
}

// 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 = 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
		}
		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
	}
	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.call(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.call(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.call(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".
func (s Sequence) Chdir(dir string) Sequence {
	if s.err != nil {
		return s
	}
	err := s.r.call(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".
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".
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".
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".
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".
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".
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". 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". 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, 0x%x, %s)", name, flag, perm))
	err = s.Done()
	return
}

// Create is a wrapper around os.Create that handles options such as "verbose"
//. 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 {
		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". 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.call(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". 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.call(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".
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".
// 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". 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.call(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". 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.call(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". Lstat is a terminating function.
func (s Sequence) Readlink(name string) (link string, err error) {
	if s.err != nil {
		return "", s.Done()
	}
	s.r.call(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". 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".
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.call(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.call(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
}
