// 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 gosh provides facilities for running and managing processes: start
// them, wait for them to exit, capture their output streams, pipe messages
// between them, terminate them (e.g. on SIGINT), and so on.
//
// Gosh is meant to be used in situations where one might otherwise be tempted
// to write a shell script. (Oh my gosh, no more shell scripts!)
//
// For usage examples, see shell_test.go and internal/gosh_example/main.go.
package gosh

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"os/signal"
	"path"
	"path/filepath"
	"sync"
	"syscall"
	"time"
)

const (
	envBinDir         = "GOSH_BIN_DIR"
	envChildOutputDir = "GOSH_CHILD_OUTPUT_DIR"
	envExitAfter      = "GOSH_EXIT_AFTER"
	envInvocation     = "GOSH_INVOCATION"
	envWatchParent    = "GOSH_WATCH_PARENT"
)

var (
	errAlreadyCalledCleanup = errors.New("gosh: already called Shell.Cleanup")
	errDidNotCallInitMain   = errors.New("gosh: did not call gosh.InitMain")
	errDidNotCallNewShell   = errors.New("gosh: did not call gosh.NewShell")
)

// Shell represents a shell. Not thread-safe.
type Shell struct {
	// Err is the most recent error from this Shell or any of its Cmds (may be
	// nil).
	Err error
	// Opts is the Opts struct for this Shell, with default values filled in.
	Opts Opts
	// Vars is the map of env vars for this Shell.
	Vars map[string]string
	// Args is the list of args to append to subsequent command invocations.
	Args []string
	// Internal state.
	calledNewShell  bool
	cleanupDone     chan struct{}
	cleanupMu       sync.Mutex // protects the fields below; held during cleanup
	calledCleanup   bool
	cmds            []*Cmd
	tempFiles       []*os.File
	tempDirs        []string
	dirStack        []string // for pushd/popd
	cleanupHandlers []func()
}

// Opts configures Shell.
type Opts struct {
	// Fatalf is called whenever an error is encountered.
	// If not specified, defaults to panic(fmt.Sprintf(format, v...)).
	Fatalf func(format string, v ...interface{})
	// Logf is called to log things.
	// If not specified, defaults to log.Printf(format, v...).
	Logf func(format string, v ...interface{})
	// Child stdout and stderr are propagated up to the parent's stdout and stderr
	// iff PropagateChildOutput is true.
	PropagateChildOutput bool
	// If specified, each child's stdout and stderr streams are also piped to
	// files in this directory.
	// If not specified, defaults to GOSH_CHILD_OUTPUT_DIR.
	ChildOutputDir string
	// Directory where BuildGoPkg() writes compiled binaries.
	// If not specified, defaults to GOSH_BIN_DIR.
	BinDir string
}

// NewShell returns a new Shell.
func NewShell(opts Opts) *Shell {
	sh, err := newShell(opts)
	sh.HandleError(err)
	return sh
}

// HandleError sets sh.Err. If err is not nil, it also calls sh.Opts.Fatalf.
func (sh *Shell) HandleError(err error) {
	sh.Ok()
	sh.Err = err
	if err != nil && sh.Opts.Fatalf != nil {
		sh.Opts.Fatalf("%v", err)
	}
}

// Cmd returns a Cmd for an invocation of the named program. The given arguments
// are passed to the child as command-line arguments.
func (sh *Shell) Cmd(name string, args ...string) *Cmd {
	sh.Ok()
	res, err := sh.cmd(nil, name, args...)
	sh.HandleError(err)
	return res
}

// FuncCmd returns a Cmd for an invocation of the given registered Func. The
// given arguments are gob-encoded in the parent process, then gob-decoded in
// the child and passed to the Func as parameters. To specify command-line
// arguments for the child invocation, append to the returned Cmd's Args.
func (sh *Shell) FuncCmd(f *Func, args ...interface{}) *Cmd {
	sh.Ok()
	res, err := sh.funcCmd(f, args...)
	sh.HandleError(err)
	return res
}

// Wait waits for all commands started by this Shell to exit.
func (sh *Shell) Wait() {
	sh.Ok()
	sh.HandleError(sh.wait())
}

// Rename renames (moves) a file. It's just like os.Rename, but retries once on
// error.
func (sh *Shell) Rename(oldpath, newpath string) {
	sh.Ok()
	sh.HandleError(sh.rename(oldpath, newpath))
}

// BuildGoPkg compiles a Go package using the "go build" command and writes the
// resulting binary to sh.Opts.BinDir. Returns the absolute path to the binary.
// Included in Shell for convenience, but could have just as easily been
// provided as a utility function.
func (sh *Shell) BuildGoPkg(pkg string, flags ...string) string {
	sh.Ok()
	res, err := sh.buildGoPkg(pkg, flags...)
	sh.HandleError(err)
	return res
}

// MakeTempFile creates a new temporary file in os.TempDir, opens the file for
// reading and writing, and returns the resulting *os.File.
func (sh *Shell) MakeTempFile() *os.File {
	sh.Ok()
	res, err := sh.makeTempFile()
	sh.HandleError(err)
	return res
}

// MakeTempDir creates a new temporary directory in os.TempDir and returns the
// path of the new directory.
func (sh *Shell) MakeTempDir() string {
	sh.Ok()
	res, err := sh.makeTempDir()
	sh.HandleError(err)
	return res
}

// Pushd behaves like Bash pushd.
func (sh *Shell) Pushd(dir string) {
	sh.Ok()
	sh.HandleError(sh.pushd(dir))
}

// Popd behaves like Bash popd.
func (sh *Shell) Popd() {
	sh.Ok()
	sh.HandleError(sh.popd())
}

// AddCleanupHandler registers the given function to be called during cleanup.
// Cleanup handlers are called in LIFO order, possibly in a separate goroutine
// spawned by gosh.
func (sh *Shell) AddCleanupHandler(f func()) {
	sh.Ok()
	sh.HandleError(sh.addCleanupHandler(f))
}

// Cleanup cleans up all resources (child processes, temporary files and
// directories) associated with this Shell. It is safe (and recommended) to call
// Cleanup after a Shell error. It is also safe to call Cleanup multiple times;
// calls after the first return immediately with no effect. Cleanup never calls
// HandleError.
func (sh *Shell) Cleanup() {
	if !sh.calledNewShell {
		panic(errDidNotCallNewShell)
	}
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if !sh.calledCleanup {
		sh.cleanup()
	}
}

// Ok panics iff this Shell is in a state where it's invalid to call other
// methods. This method is public to facilitate Shell wrapping.
func (sh *Shell) Ok() {
	if !sh.calledNewShell {
		panic(errDidNotCallNewShell)
	}
	// Panic on incorrect usage of Shell.
	if sh.Err != nil {
		panic(fmt.Errorf("gosh: Shell.Err is not nil: %v", sh.Err))
	}
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		panic(errAlreadyCalledCleanup)
	}
}

////////////////////////////////////////
// Internals

// Note: On error, newShell returns a *Shell with Opts.Fatalf initialized to
// simplify things for the caller.
func newShell(opts Opts) (*Shell, error) {
	osVars := sliceToMap(os.Environ())
	if opts.Fatalf == nil {
		opts.Fatalf = func(format string, v ...interface{}) {
			panic(fmt.Sprintf(format, v...))
		}
	}
	if opts.Logf == nil {
		opts.Logf = func(format string, v ...interface{}) {
			log.Printf(format, v...)
		}
	}
	if opts.ChildOutputDir == "" {
		opts.ChildOutputDir = osVars[envChildOutputDir]
	}
	// Filter out any gosh env vars coming from outside.
	shVars := copyMap(osVars)
	for _, key := range []string{envBinDir, envChildOutputDir, envExitAfter, envInvocation, envWatchParent} {
		delete(shVars, key)
	}
	sh := &Shell{
		Opts:           opts,
		Vars:           shVars,
		calledNewShell: true,
		cleanupDone:    make(chan struct{}),
	}
	if sh.Opts.BinDir == "" {
		sh.Opts.BinDir = osVars[envBinDir]
		if sh.Opts.BinDir == "" {
			var err error
			if sh.Opts.BinDir, err = sh.makeTempDir(); err != nil {
				sh.cleanup()
				return sh, err
			}
		}
	}
	sh.cleanupOnSignal()
	return sh, nil
}

// cleanupOnSignal starts a goroutine that calls cleanup if a termination signal
// is received.
func (sh *Shell) cleanupOnSignal() {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
	go func() {
		select {
		case sig := <-ch:
			// A termination signal was received; the process will exit.
			sh.logf("Received signal: %v\n", sig)
			sh.cleanupMu.Lock()
			defer sh.cleanupMu.Unlock()
			if !sh.calledCleanup {
				sh.cleanup()
			}
			// Note: We hold cleanupMu during os.Exit(1) so that the main goroutine
			// will not call Shell.Ok() and panic before we exit.
			os.Exit(1)
		case <-sh.cleanupDone:
			// The user called sh.Cleanup; stop listening for signals and exit this
			// goroutine.
		}
		signal.Stop(ch)
	}()
}

func (sh *Shell) logf(format string, v ...interface{}) {
	if sh.Opts.Logf != nil {
		sh.Opts.Logf(format, v...)
	}
}

func (sh *Shell) cmd(vars map[string]string, name string, args ...string) (*Cmd, error) {
	if vars == nil {
		vars = make(map[string]string)
	}
	c, err := newCmd(sh, mergeMaps(sh.Vars, vars), name, append(args, sh.Args...)...)
	if err != nil {
		return nil, err
	}
	c.PropagateOutput = sh.Opts.PropagateChildOutput
	c.OutputDir = sh.Opts.ChildOutputDir
	return c, nil
}

var executablePath = os.Args[0]

func init() {
	// If exec.LookPath fails, hope for the best.
	if lp, err := exec.LookPath(executablePath); err != nil {
		executablePath = lp
	}
}

func (sh *Shell) funcCmd(f *Func, args ...interface{}) (*Cmd, error) {
	// Safeguard against the developer forgetting to call InitMain, which could
	// lead to infinite recursion.
	if !calledInitMain {
		return nil, errDidNotCallInitMain
	}
	buf, err := encodeInvocation(f.handle, args...)
	if err != nil {
		return nil, err
	}
	vars := map[string]string{envInvocation: string(buf)}
	return sh.cmd(vars, executablePath)
}

func (sh *Shell) wait() error {
	// Note: It is illegal to call newCmdInternal concurrently with Shell.wait, so
	// we need not hold cleanupMu when accessing sh.cmds below.
	var res error
	for _, c := range sh.cmds {
		if !c.started || c.calledWait {
			continue
		}
		if err := c.wait(); !c.errorIsOk(err) {
			sh.logf("%s (PID %d) failed: %v\n", c.Path, c.Pid(), err)
			res = err
		}
	}
	return res
}

func (sh *Shell) rename(oldpath, newpath string) error {
	if err := os.Rename(oldpath, newpath); err != nil {
		// Concurrent, same-directory rename operations sometimes fail on certain
		// filesystems, so we retry once after a random backoff.
		time.Sleep(time.Duration(rand.Int63n(1000)) * time.Millisecond)
		if err := os.Rename(oldpath, newpath); err != nil {
			return err
		}
	}
	return nil
}

func (sh *Shell) buildGoPkg(pkg string, flags ...string) (string, error) {
	binPath := filepath.Join(sh.Opts.BinDir, path.Base(pkg))
	// If this binary has already been built, don't rebuild it.
	if _, err := os.Stat(binPath); err == nil {
		return binPath, nil
	} else if !os.IsNotExist(err) {
		return "", err
	}
	// Build binary to tempBinPath, then move it to binPath.
	tempDir, err := ioutil.TempDir(sh.Opts.BinDir, "")
	if err != nil {
		return "", err
	}
	defer os.RemoveAll(tempDir)
	tempBinPath := filepath.Join(tempDir, path.Base(pkg))
	args := []string{"build", "-x", "-o", tempBinPath}
	args = append(args, flags...)
	args = append(args, pkg)
	c, err := sh.cmd(nil, "go", args...)
	if err != nil {
		return "", err
	}
	c.PropagateOutput = false
	if err := c.run(); err != nil {
		return "", err
	}
	if err := sh.rename(tempBinPath, binPath); err != nil {
		return "", err
	}
	return binPath, nil
}

func (sh *Shell) makeTempFile() (*os.File, error) {
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return nil, errAlreadyCalledCleanup
	}
	f, err := ioutil.TempFile("", "")
	if err != nil {
		return nil, err
	}
	sh.tempFiles = append(sh.tempFiles, f)
	return f, nil
}

func (sh *Shell) makeTempDir() (string, error) {
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return "", errAlreadyCalledCleanup
	}
	name, err := ioutil.TempDir("", "")
	if err != nil {
		return "", err
	}
	sh.tempDirs = append(sh.tempDirs, name)
	return name, nil
}

func (sh *Shell) pushd(dir string) error {
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return errAlreadyCalledCleanup
	}
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	if err := os.Chdir(dir); err != nil {
		return err
	}
	sh.dirStack = append(sh.dirStack, cwd)
	return nil
}

func (sh *Shell) popd() error {
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return errAlreadyCalledCleanup
	}
	if len(sh.dirStack) == 0 {
		return errors.New("gosh: dir stack is empty")
	}
	dir := sh.dirStack[len(sh.dirStack)-1]
	if err := os.Chdir(dir); err != nil {
		return err
	}
	sh.dirStack = sh.dirStack[:len(sh.dirStack)-1]
	return nil
}

func (sh *Shell) addCleanupHandler(f func()) error {
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return errAlreadyCalledCleanup
	}
	sh.cleanupHandlers = append(sh.cleanupHandlers, f)
	return nil
}

// forEachRunningCmd applies f to each running child process.
func (sh *Shell) forEachRunningCmd(f func(*Cmd)) bool {
	anyRunning := false
	for _, c := range sh.cmds {
		if c.isRunning() {
			anyRunning = true
			if f != nil {
				f(c)
			}
		}
	}
	return anyRunning
}

// Note: It is safe to run Shell.terminateRunningCmds concurrently with the
// waiter goroutine and with Cmd.wait. In particular, Shell.terminateRunningCmds
// only calls c.{isRunning,Pid,signal}, all of which are thread-safe with the
// waiter goroutine and with Cmd.wait.
func (sh *Shell) terminateRunningCmds() {
	// Send os.Interrupt first; if that doesn't work, send os.Kill.
	anyRunning := sh.forEachRunningCmd(func(c *Cmd) {
		if err := c.signal(os.Interrupt); err != nil {
			sh.logf("%d.Signal(os.Interrupt) failed: %v\n", c.Pid(), err)
		}
	})
	// If any child is still running, wait for 100ms.
	if anyRunning {
		time.Sleep(100 * time.Millisecond)
		anyRunning = sh.forEachRunningCmd(func(c *Cmd) {
			sh.logf("%s (PID %d) did not die\n", c.Path, c.Pid())
		})
	}
	// If any child is still running, wait for another second, then send os.Kill
	// to all running children.
	if anyRunning {
		time.Sleep(time.Second)
		sh.forEachRunningCmd(func(c *Cmd) {
			if err := c.signal(os.Kill); err != nil {
				sh.logf("%d.Signal(os.Kill) failed: %v\n", c.Pid(), err)
			}
		})
		sh.logf("Killed all remaining child processes\n")
	}
}

func (sh *Shell) cleanup() {
	sh.calledCleanup = true
	// Terminate all children that are still running.
	sh.terminateRunningCmds()
	// Close and delete all temporary files.
	for _, tempFile := range sh.tempFiles {
		name := tempFile.Name()
		if err := tempFile.Close(); err != nil {
			sh.logf("%q.Close() failed: %v\n", name, err)
		}
		if err := os.RemoveAll(name); err != nil {
			sh.logf("os.RemoveAll(%q) failed: %v\n", name, err)
		}
	}
	// Delete all temporary directories.
	for _, tempDir := range sh.tempDirs {
		if err := os.RemoveAll(tempDir); err != nil {
			sh.logf("os.RemoveAll(%q) failed: %v\n", tempDir, err)
		}
	}
	// Change back to the top of the dir stack.
	if len(sh.dirStack) > 0 {
		dir := sh.dirStack[0]
		if err := os.Chdir(dir); err != nil {
			sh.logf("os.Chdir(%q) failed: %v\n", dir, err)
		}
	}
	// Call cleanup handlers in LIFO order.
	for i := len(sh.cleanupHandlers) - 1; i >= 0; i-- {
		sh.cleanupHandlers[i]()
	}
	close(sh.cleanupDone)
}

////////////////////////////////////////
// Public utilities

var calledInitMain = false

// InitMain must be called early on in main(), before flags are parsed. In the
// parent process, it returns immediately with no effect. In a child process for
// a Shell.FuncCmd command, it runs the specified function, then exits.
func InitMain() {
	calledInitMain = true
	s := os.Getenv(envInvocation)
	if s == "" {
		return
	}
	os.Unsetenv(envInvocation)
	InitChildMain()
	name, args, err := decodeInvocation(s)
	if err != nil {
		log.Fatal(err)
	}
	if err := callFunc(name, args...); err != nil {
		log.Fatal(err)
	}
	os.Exit(0)
}
