// 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"
	"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).
//
// When not in verbose mode (set either via NewSequence or an Opt) output
// from commands will be suppressed unless they return an error. When
// verbose mode is set, all output is written to the supplied stdout
// and stderr.
//
// Modifier methods are provided that influence the behaviour of the
// next invocation of the Run method to set timeouts (Timeout) and to
// capture output (Capture), an additional modifier method (Opts) is
// provided the set the options for the remaining methods and is generally
// used to control logging.
// For example, the following will result in a timeout error.
//
// err := s.Timed(time.Second).Run("sleep","10").Done()
// err := s.Timed(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.Opts(o).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, but Opts can be used to control logging.
type Sequence struct {
	r              *Run
	err            error
	caller         string
	stdout, stderr io.Writer
	opts           *Opts
	dirs           []string
	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)}
}

// Capture arranges for the next call to Run to write its stdout and stderr
// output to the supplied io.Writers. This will be cleared and not used for
// any calls to Run beyond the next one.
func (s *Sequence) Capture(stdout, stderr io.Writer) *Sequence {
	if s.err != nil {
		return s
	}
	s.stdout, s.stderr = stdout, stderr
	return s
}

// Opts arranges for the next call to Run to use the supplied options.
// They will be cleared and not used for any calls to Run beyond the next one.
func (s *Sequence) Opts(opts Opts) *Sequence {
	if s.err != nil {
		return s
	}
	s.opts = &opts
	return s
}

// Timeout arranges for the next call to Run to be subject to the specified
// timeout. The timeout will be cleared and not used any calls to Run beyond
// the next one.
func (s *Sequence) Timeout(timeout time.Duration) *Sequence {
	if s.err != nil {
		return s
	}
	s.timeout = timeout
	return s
}

func (s *Sequence) GetOpts() Opts {
	if s.opts != nil {
		return *s.opts
	}
	return s.r.Opts()
}

func (s *Sequence) Error() error {
	if s.err != nil && len(s.caller) > 0 {
		return fmt.Errorf("%s: %v", s.caller, s.err)
	}
	return s.err
}

func (s *Sequence) setOpts(opts Opts) {
	s.opts = &opts
}

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.stdout, s.stderr, s.opts = nil, nil, nil
	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 (s *Sequence) initAndDefer() func() {
	if s.stdout == nil && s.stderr == nil {
		f, err := ioutil.TempFile("", "seq")
		if err != nil {
			return func() {}
		}
		opts := s.GetOpts()
		stdout := opts.Stdout
		opts.Stdout = f
		opts.Stderr = f
		s.setOpts(opts)
		return func() {
			filename := f.Name()
			f.Close()
			if opts.Verbose || s.err != nil {
				// TODO(cnicolaou): probably best to stream this out rather
				// than buffer the whole file into memory.
				data, err := ioutil.ReadFile(filename)
				if err == nil {
					fmt.Fprint(stdout, string(data))
				}
			}
			os.Remove(filename)
			s.opts = nil
		}
	}
	opts := s.GetOpts()
	rStdin, wStdin := io.Pipe()
	rStderr, wStderr := io.Pipe()
	opts.Stdout = wStdin
	opts.Stderr = wStderr
	s.setOpts(opts)
	var stdinCh, stderrCh chan error
	if s.stdout != nil {
		stdinCh = make(chan error)
		go copy(s.stdout, rStdin, stdinCh)
	}
	if s.stderr != nil {
		stderrCh = make(chan error)
		go copy(s.stderr, rStderr, stderrCh)
	}
	return func() {
		if err := s.done(wStdin, wStderr, stdinCh, stderrCh); err != nil && s.err == nil {
			s.err = err
		}
	}
}

func fmtArgs(args ...interface{}) string {
	if len(args) == 0 {
		return ""
	}
	out := &bytes.Buffer{}
	for _, a := range args {
		if _, ok := a.(string); ok {
			out.WriteString(fmt.Sprintf(" ,%q", a))
		} else {
			out.WriteString(fmt.Sprintf(" ,%s", a))
		}
	}
	return out.String()
}

func fmtStringArgs(args ...string) string {
	if len(args) == 0 {
		return ""
	}
	out := &bytes.Buffer{}
	for _, a := range args {
		out.WriteString(", \"")
		out.WriteString(a)
		out.WriteString("\"")
	}
	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%s)", fn, 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
}

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

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

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

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