package modules

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"sync"
	"time"

	"veyron.io/veyron/veyron2/vlog"

	vexec "veyron.io/veyron/veyron/lib/exec"
)

// execHandle implements both the command and Handle interfaces.
type execHandle struct {
	mu         sync.Mutex
	cmd        *exec.Cmd
	entryPoint string
	handle     *vexec.ParentHandle
	sh         *Shell
	stderr     *os.File
	stdout     io.ReadCloser
	stdin      io.WriteCloser
}

func testFlags() []string {
	var fl []string
	// pass logging flags to any subprocesses
	for fname, fval := range vlog.Log.ExplicitlySetFlags() {
		fl = append(fl, "--"+fname+"="+fval)
	}
	timeout := flag.Lookup("test.timeout")
	if timeout == nil {
		// not a go test binary
		return fl
	}
	// must be a go test binary
	fl = append(fl, "-test.run=TestHelperProcess")
	val := timeout.Value.(flag.Getter).Get().(time.Duration)
	if val.String() != timeout.DefValue {
		// use supplied command value for subprocesses
		fl = append(fl, "--test.timeout="+timeout.Value.String())
	} else {
		// translate default value into 1m for subproccesses
		fl = append(fl, "--test.timeout=1m")
	}
	return fl
}

// IsTestHelperProces returns true if it is called in via
// -run=TestHelperProcess which normally only ever happens for subprocesses
// run from tests.
func IsTestHelperProcess() bool {
	runFlag := flag.Lookup("test.run")
	if runFlag == nil {
		return false
	}
	return runFlag.Value.String() == "TestHelperProcess"
}

func newExecHandle(entryPoint string) command {
	return &execHandle{entryPoint: entryPoint}
}

func (eh *execHandle) Stdout() io.Reader {
	eh.mu.Lock()
	defer eh.mu.Unlock()
	return eh.stdout
}

func (eh *execHandle) Stderr() io.Reader {
	eh.mu.Lock()
	defer eh.mu.Unlock()
	return eh.stderr
}

func (eh *execHandle) Stdin() io.Writer {
	eh.mu.Lock()
	defer eh.mu.Unlock()
	return eh.stdin
}

func (eh *execHandle) CloseStdin() {
	eh.mu.Lock()
	eh.stdin.Close()
	eh.mu.Unlock()
}

// mergeOSEnv returns a slice contained the merged set of environment
// variables from the OS environment and those in this Shell, preferring
// values in the Shell environment over those found in the OS environment.
func (sh *Shell) mergeOSEnvSlice() []string {
	merged := sh.mergeOSEnv()
	env := []string{}
	for k, v := range merged {
		env = append(env, k+"="+v)
	}
	return env
}

func osEnvironMap() map[string]string {
	m := make(map[string]string)
	for _, osv := range os.Environ() {
		if len(osv) == 0 {
			continue
		}
		parts := strings.SplitN(osv, "=", 2)
		key := parts[0]
		if len(parts) == 2 {
			m[key] = parts[1]
		} else {
			m[key] = ""
		}
	}
	return m
}
func (sh *Shell) mergeOSEnv() map[string]string {
	merged := osEnvironMap()
	sh.mu.Lock()
	for k, v := range sh.env {
		merged[k] = v
	}
	sh.mu.Unlock()
	return merged
}

func (eh *execHandle) start(sh *Shell, args ...string) (Handle, error) {
	eh.mu.Lock()
	defer eh.mu.Unlock()
	eh.sh = sh
	newargs := append(testFlags(), args...)
	cmd := exec.Command(os.Args[0], newargs...)
	cmd.Env = append(sh.mergeOSEnvSlice(), eh.entryPoint)
	fname := strings.TrimPrefix(eh.entryPoint, ShellEntryPoint+"=")
	stderr, err := newLogfile(strings.TrimLeft(fname, "-\n\t "))
	if err != nil {
		return nil, err
	}
	cmd.Stderr = stderr
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stdin, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}

	handle := vexec.NewParentHandle(cmd)
	eh.stdout = stdout
	eh.stderr = stderr
	eh.stdin = stdin
	eh.handle = handle
	eh.cmd = cmd
	if err := handle.Start(); err != nil {
		return nil, err
	}
	err = handle.WaitForReady(10 * time.Second)
	return eh, err
}

func (eh *execHandle) Pid() int {
	return eh.cmd.Process.Pid
}

func (eh *execHandle) Shutdown(stdout, stderr io.Writer) error {
	eh.mu.Lock()
	defer eh.mu.Unlock()
	eh.stdin.Close()
	logFile := eh.stderr.Name()
	defer eh.sh.forget(eh)

	defer func() {
		os.Remove(logFile)
	}()

	if stdout == nil && stderr == nil {
		return eh.cmd.Wait()
	}
	// Read from stdin before waiting for the child process to ensure
	// that we get to read all of its output.
	readTo(eh.stdout, stdout)

	procErr := eh.cmd.Wait()

	// Stderr is buffered to a file, so we can safely read it after we
	// wait for the process.
	eh.stderr.Close()
	stderrFile, err := os.Open(logFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "failed to open %q: %s", logFile, err)
		return procErr
	}
	readTo(stderrFile, stderr)
	stderrFile.Close()
	return procErr
}

const ShellEntryPoint = "VEYRON_SHELL_HELPER_PROCESS_ENTRY_POINT"

func RegisterChild(name, help string, main Main) {
	child.Lock()
	defer child.Unlock()
	child.mains[name] = &childEntryPoint{main, help}
}

// DispatchInTest will execute the requested subproccess command from within
// a unit test run as a subprocess.
func DispatchInTest() {
	if !IsTestHelperProcess() {
		return
	}
	if err := child.dispatch(); err != nil {
		fmt.Fprintf(os.Stderr, "Failed: %s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

// Dispatch will execute the requested subprocess command from a within a
// a subprocess that is not a unit test.
func Dispatch() error {
	if IsTestHelperProcess() {
		return fmt.Errorf("use DispatchInTest in unittests")
	}
	return child.dispatch()
}

func (child *childRegistrar) hasCommand(name string) bool {
	child.Lock()
	_, present := child.mains[name]
	child.Unlock()
	return present
}

func (child *childRegistrar) dispatch() error {
	ch, _ := vexec.GetChildHandle()
	// Only signal that the child is ready or failed if we successfully get
	// a child handle. We most likely failed to get a child handle
	// because the subprocess was run directly from the command line.

	command := os.Getenv(ShellEntryPoint)
	if len(command) == 0 {
		err := fmt.Errorf("Failed to find entrypoint %q", ShellEntryPoint)
		if ch != nil {
			ch.SetFailed(err)
		}
		return err
	}

	child.Lock()
	m := child.mains[command]
	child.Unlock()

	if m == nil {
		err := fmt.Errorf("Shell command %q not registered", command)
		if ch != nil {
			ch.SetFailed(err)
		}
		return err
	}

	if ch != nil {
		ch.SetReady()
	}

	go func(pid int) {
		for {
			_, err := os.FindProcess(pid)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Looks like our parent exited: %v", err)
				os.Exit(1)
			}
			time.Sleep(time.Second)
		}
	}(os.Getppid())

	return m.fn(os.Stdin, os.Stdout, os.Stderr, osEnvironMap(), flag.Args()...)
}

func (child *childRegistrar) addSubprocesses(sh *Shell, pattern string) error {
	re, err := regexp.Compile(pattern)
	if err != nil {
		return err
	}
	child.Lock()
	defer child.Unlock()
	found := false
	for name, subproc := range child.mains {
		if re.MatchString(name) {
			sh.addSubprocess(name, subproc.help)
			found = true
		}
	}
	if !found {
		return fmt.Errorf("patterh %q failed to match any registered commands", pattern)
	}
	return nil
}

// AddRegisteredSubprocesses adds any commands that match the regexp pattern
// to the supplied shell.
func AddRegisteredSubprocesses(sh *Shell, pattern string) error {
	return child.addSubprocesses(sh, pattern)
}

// WaitForEof returns when a read on its io.Reader parameter returns io.EOF
func WaitForEOF(stdin io.Reader) {
	buf := [1024]byte{}
	for {
		if _, err := stdin.Read(buf[:]); err == io.EOF {
			return
		}
	}
}
