// 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).
// 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 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
	serializedWriterLock         sync.Mutex
}

// 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 {
	s := &Sequence{
		r:            NewRun(env, stdin, stdout, stderr, color, dryRun, verbose),
		defaultStdin: stdin,
	}
	s.defaultStdout, s.defaultStderr = s.serializeWriter(stdout), s.serializeWriter(stderr)
	return s
}

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

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

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

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, opts.Stderr = s.serializeWriter(fout), s.serializeWriter(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, 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
	}
	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.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.err
}

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