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

// 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                            *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{
		&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 Sequence{s.sequence}
	}
	s.stdout, s.stderr = stdout, stderr
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.reading = true
	s.stdin = stdin
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.env = env
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.verbosity = &verbosity
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.timeout = timeout
	return Sequence{s.sequence}
}

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 Sequence{s.sequence}.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)
}

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

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(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()
	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 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 Sequence{s.sequence}
	}
	s.dirs = append(s.dirs, cwd)
	s.setError(s.r.Chdir(dir), "Pushd("+dir+")")
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	if len(s.dirs) == 0 {
		s.setError(fmt.Errorf("directory stack is empty"), "Popd()")
		return Sequence{s.sequence}
	}
	last := s.dirs[len(s.dirs)-1]
	s.dirs = s.dirs[:len(s.dirs)-1]
	s.setError(s.r.Chdir(last), "Popd() -> "+last)
	return Sequence{s.sequence}
}

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

// 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 Sequence{s.sequence}.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 Sequence{s.sequence}
	}
	defer s.initAndDefer()()
	s.setError(s.r.FunctionWithOpts(s.getOpts(), fn, format, args...), fmt.Sprintf(format, args))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.Chdir(dir), "Chdir("+dir+")")
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	if err := s.r.Chmod(dir, mode); err != nil {
		s.setError(err, fmt.Sprintf("Chmod(%s, %s)", dir, mode))
	}
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.MkdirAll(dir, mode), fmt.Sprintf("MkdirAll(%s, %s)", dir, mode))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.RemoveAll(dir), fmt.Sprintf("RemoveAll(%s)", dir))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.Remove(file), fmt.Sprintf("Remove(%s)", file))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.Rename(src, dst), fmt.Sprintf("Rename(%s, %s)", src, dst))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	s.setError(s.r.Symlink(src, dst), fmt.Sprintf("Symlink(%s, %s)", src, dst))
	return Sequence{s.sequence}
}

// 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 Sequence{s.sequence}
	}
	opts := s.getOpts()
	if s.verbosity != nil {
		opts.Verbose = *s.verbosity
	}
	s.r.OutputWithOpts(opts, output)
	return Sequence{s.sequence}
}

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

// 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 Sequence{s.sequence}
	}
	err := s.r.WriteFile(filename, data, perm)
	s.setError(err, fmt.Sprintf("WriteFile(%s, %10s,  %s)", filename, data, perm))
	return Sequence{s.sequence}
}

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