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

	"fuchsia.googlesource.com/jiri/cmdline"
	"fuchsia.googlesource.com/jiri/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 and stderr io.Writers configured via NewSequence,
// and never to the stdout specified via Capture if the command succeeded.
//
// 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
// fuchsia.googlesource.com/jiri/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, verbose bool) Sequence {
	if len(env) == 0 {
		env = envvar.SliceToMap(os.Environ())
	}
	s := Sequence{
		&sequence{
			r:            newExecutor(env, stdin, stdout, stderr, 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
}

// CaptureAll arranges for all the logs/outputs to write to its supplied io.Writers.
// 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) CaptureAll(stdout, stderr io.Writer) Sequence {
	if s.err != nil {
		return s
	}
	s.stdout, s.stderr = stdout, stderr
	s.r.opts.stdout, s.r.opts.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
}
