// 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"
	"path/filepath"
	"runtime"
	"sync"
	"time"
)

// 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).
//
// 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 addtion 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.
type Sequence struct {
	r                            *Run
	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
	timeout                      time.Duration
}

// NewSequence creates an instance of Sequence with default values for its
// environment, stdin, stderr, stdout and other supported options.
func NewSequence(env map[string]string, stdin io.Reader, stdout, stderr io.Writer, color, dryRun, verbose bool) *Sequence {
	return &Sequence{
		r:             NewRun(env, stdin, stdout, stderr, color, dryRun, verbose),
		defaultStdin:  stdin,
		defaultStdout: stdout,
		defaultStderr: stderr,
	}
}

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

// Env arranges for the next call to Run, Call or Last to use the supplied
// environment variables. This 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
	}
	s.env = env
	return s
}

// Verbosity arranges for the next call to Run, Call 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
}

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

// GetOriginalError gets the original error wrapped in the given err.
// If the given err is not a wrappedError, just return itself.
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)
}

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)
}

func (s *Sequence) reset() {
	s.stdin, s.stdout, s.stderr, s.env = nil, nil, nil, nil
	s.opts, s.verbosity = nil, nil
	s.reading = false
	s.timeout = 0
}

func (s *Sequence) done(p1, p2 *io.PipeWriter, stdinCh, stderrCh chan error) error {
	p1.Close()
	p2.Close()
	defer s.reset()
	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(from string, to io.Writer) {
	if fi, err := os.Open(from); err == nil {
		io.Copy(to, fi)
		fi.Close()
	}
	if wd, err := os.Getwd(); err == nil {
		fmt.Fprintf(to, "Current Directory: %v\n", wd)
	}
}

type lockedWriter struct {
	sync.Mutex
	f io.Writer
}

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

func (s *Sequence) initAndDefer() func() {
	if s.stdout == nil && s.stderr == nil {
		fout, err := ioutil.TempFile("", "seq")
		if err != nil {
			return func() {}
		}
		opts := s.getOpts()
		opts.Stdout = fout
		opts.Stderr = fout
		opts.Env = s.env
		if s.reading {
			opts.Stdin = s.stdin
		}
		if s.verbosity != nil {
			opts.Verbose = *s.verbosity
		}
		s.setOpts(opts)
		return func() {
			filename := fout.Name()
			fout.Close()
			defer func() { os.Remove(filename); s.opts = nil }()
			if s.err != nil {
				writeOutput(filename, useIfNotNil(s.defaultStderr, os.Stderr))
			}
			if opts.Verbose && s.defaultStderr != s.defaultStdout {
				writeOutput(filename, useIfNotNil(s.defaultStdout, os.Stdout))
			}
		}
	}
	opts := s.getOpts()
	rStdout, wStdout := io.Pipe()
	rStderr, wStderr := io.Pipe()
	opts.Stdout = wStdout
	opts.Stderr = wStderr
	opts.Env = s.env
	if s.reading {
		opts.Stdin = s.stdin
	}
	var stdinCh, stderrCh chan error
	stdout := s.stdout
	stderr := s.stderr
	if stdout != nil {
		if stdout == stderr {
			stdout = &lockedWriter{f: stdout}
			stderr = &lockedWriter{f: stderr}
		}
		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
	}
	s.setOpts(opts)
	return func() {
		if err := s.done(wStdout, wStderr, stdinCh, stderrCh); err != nil && s.err == nil {
			s.err = err
		}
	}
}

func fmtArgs(args ...interface{}) string {
	if len(args) == 0 {
		return ""
	}
	var out bytes.Buffer
	for _, a := range args {
		switch at := a.(type) {
		case string:
			fmt.Fprintf(&out, ", %q", at)
		default:
			fmt.Fprintf(&out, ", %v", a)
		}
	}
	return out.String()
}

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()
}

// 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)
	s.setError(s.r.Chdir(dir), "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]
	s.setError(s.r.Chdir(last), "Popd() -> "+last)
	return s
}

// 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()()
	s.setError(s.r.command(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.initAndDefer()()
	s.setError(s.r.command(s.timeout, s.getOpts(), path, args...), fmt.Sprintf("Last(%q%s)", path, fmtStringArgs(args...)))
	return s.Done()
}

// 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()()
	s.setError(s.r.FunctionWithOpts(s.getOpts(), fn, format, args...), fmt.Sprintf("Call(%s%s)", format, fmtArgs(args)))
	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
	}
	s.setError(s.r.Chdir(dir), "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
	}
	if err := s.r.Chmod(dir, mode); err != nil {
		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
	}
	s.setError(s.r.MkdirAll(dir, mode), 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
	}
	s.setError(s.r.RemoveAll(dir), 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
	}
	s.setError(s.r.Remove(file), 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
	}
	s.setError(s.r.Rename(src, dst), 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
	}
	s.setError(s.r.Symlink(src, dst), fmt.Sprintf("Symlink(%s, %s)", src, dst))
	return s
}

// 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
	}
	s.r.OutputWithOpts(s.getOpts(), 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
		if err := s.r.Chdir(cwd); 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
}

// 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) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.Open(name)
	s.setError(err, fmt.Sprintf("Open(%s)", name))
	return f, s.Done()
}

// 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) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.OpenFile(name, flag, perm)
	s.setError(err, fmt.Sprintf("OpenFile(%s, %s, %s)", name, flag, perm))
	return f, s.Done()
}

// 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) (*os.File, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	f, err := s.r.Create(name)
	s.setError(err, fmt.Sprintf("Create(%s)", name))
	return f, s.Done()
}

// 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) ([]os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.ReadDir(dirname)
	s.setError(err, fmt.Sprintf("ReadDir(%s)", dirname))
	return fi, s.Done()
}

// 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) ([]byte, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	data, err := s.r.ReadFile(filename)
	s.setError(err, fmt.Sprintf("ReadFile(%s)", filename))
	return data, s.Done()
}

// 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.WriteFile(filename, data, perm)
	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 *os.File, src io.Reader) (int64, error) {
	if s.err != nil {
		return 0, s.Done()
	}
	n, err := s.r.Copy(dst, src)
	s.setError(err, fmt.Sprintf("Copy(%s, %s)", dst, src))
	return n, s.Done()
}

// 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) (os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.Stat(name)
	s.setError(err, fmt.Sprintf("Stat(%s)", name))
	return fi, s.Done()
}

// 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) (os.FileInfo, error) {
	if s.err != nil {
		return nil, s.Done()
	}
	fi, err := s.r.Lstat(name)
	s.setError(err, fmt.Sprintf("Lstat(%s)", name))
	return fi, s.Done()
}

// 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) (string, error) {
	if s.err != nil {
		return "", s.Done()
	}
	link, err := s.r.Readlink(name)
	s.setError(err, fmt.Sprintf("Readlink(%s)", name))
	return link, s.Done()
}

// 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) (string, error) {
	if s.err != nil {
		return "", s.Done()
	}
	name, err := s.r.TempDir(dir, prefix)
	s.setError(err, fmt.Sprintf("TempDir(%s,%s)", dir, prefix))
	return name, s.Done()
}

// IsDir is a wrapper around os.Stat with appropriate logging.
// IsDir is a terminating function.
func (s *Sequence) IsDir(dirname string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	t, err := s.r.IsDir(dirname)
	s.setError(err, fmt.Sprintf("IsDir(%s)", dirname))
	return t, s.Done()
}

// DirExists tests if a directory exists with appropriate logging.
// DirExists is a terminating function.
func (s *Sequence) DirectoryExists(dir string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	isdir, err := s.r.IsDir(dir)
	if err != nil {
		return false, s.Done()
	}
	return isdir, s.Done()
}

// FileExists tests if a file exists with appropriate logging.
// FileExists is a terminating function.
func (s *Sequence) FileExists(file string) (bool, error) {
	if s.err != nil {
		return false, s.Done()
	}
	_, err := s.r.Stat(file)
	return err == nil, s.Done()
}

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