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

import (
	"bytes"
	"flag"
	"fmt"
	"go/doc"
	"io"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"

	"v.io/x/lib/textutil"
)

const missingDescription = "No description available"

// helpRunner is a Runner that implements the "help" functionality.  Help is
// requested for the last command in path, which must not be empty.
type helpRunner struct {
	path []*Command
	*helpConfig
}

func makeHelpRunner(path []*Command, env *Env) helpRunner {
	return helpRunner{path, &helpConfig{
		style:     env.style(),
		width:     env.width(),
		prefix:    env.prefix(),
		firstCall: env.firstCall(),
	}}
}

// helpConfig holds configuration data for help.  The style and width may be
// overriden by flags if the command returned by newCommand is parsed.
type helpConfig struct {
	style     style
	width     int
	prefix    string
	firstCall bool
}

// Run implements the Runner interface method.
func (h helpRunner) Run(env *Env, args []string) error {
	w := textutil.NewUTF8LineWriter(env.Stdout, h.width)
	defer w.Flush()
	return runHelp(w, env, args, h.path, h.helpConfig)
}

// usageFunc is used as the implementation of the Env.Usage function.
func (h helpRunner) usageFunc(env *Env, writer io.Writer) {
	w := textutil.NewUTF8LineWriter(writer, h.width)
	usage(w, env, h.path, h.helpConfig, h.helpConfig.firstCall)
	w.Flush()
}

const (
	helpName  = "help"
	helpShort = "Display help for commands or topics"
)

// newCommand returns a new help command that uses h as its Runner.
func (h helpRunner) newCommand() *Command {
	help := &Command{
		Runner: h,
		Name:   helpName,
		Short:  helpShort,
		Long: `
Help with no args displays the usage of the parent command.

Help with args displays the usage of the specified sub-command or help topic.

"help ..." recursively displays help for all commands and topics.
`,
		ArgsName: "[command/topic ...]",
		ArgsLong: `
[command/topic ...] optionally identifies a specific sub-command or help topic.
`,
	}
	help.Flags.Var(&h.style, "style", `
The formatting style for help output:
   compact   - Good for compact cmdline output.
   full      - Good for cmdline output, shows all global flags.
   godoc     - Good for godoc processing.
   shortonly - Only output short description.
Override the default by setting the CMDLINE_STYLE environment variable.
`)
	help.Flags.IntVar(&h.width, "width", h.width, `
Format output to this target width in runes, or unlimited if width < 0.
Defaults to the terminal width if available.  Override the default by setting
the CMDLINE_WIDTH environment variable.
`)
	// Override default values, so that the godoc style shows good defaults.
	help.Flags.Lookup("style").DefValue = "compact"
	help.Flags.Lookup("width").DefValue = "<terminal width>"
	cleanTree(help)
	return help
}

// runHelp implements the run-time behavior of the help command.
func runHelp(w *textutil.LineWriter, env *Env, args []string, path []*Command, config *helpConfig) error {
	if len(args) == 0 {
		usage(w, env, path, config, config.firstCall)
		return nil
	}
	if args[0] == "..." {
		usageAll(w, env, path, config, config.firstCall)
		return nil
	}
	// Look for matching children.
	cmd, cmdPath := path[len(path)-1], pathName(config.prefix, path)
	subName, subArgs := args[0], args[1:]
	for _, child := range cmd.Children {
		if child.Name == subName {
			return runHelp(w, env, subArgs, append(path, child), config)
		}
	}
	if helpName == subName {
		help := helpRunner{path, config}.newCommand()
		return runHelp(w, env, subArgs, append(path, help), config)
	}
	if cmd.LookPath {
		// Look for a matching executable in PATH.
		extName := cmd.Name + "-" + subName
		if lookPath(env, extName) {
			runner := binaryRunner{extName, cmdPath}
			envCopy := env.clone()
			envCopy.Vars["CMDLINE_STYLE"] = config.style.String()
			if len(subArgs) == 0 {
				return runner.Run(envCopy, []string{"-help"})
			}
			return runner.Run(envCopy, append([]string{helpName}, subArgs...))
		}
	}
	// Look for matching topic.
	for _, topic := range cmd.Topics {
		if topic.Name == subName {
			fmt.Fprintln(w, topic.Long)
			return nil
		}
	}
	fn := helpRunner{path, config}.usageFunc
	return usageErrorf(env, fn, "%s: unknown command or topic %q", cmdPath, subName)
}

func godocHeader(path, short string) string {
	// The first rune must be uppercase for godoc to recognize the string as a
	// section header, which is linked to the table of contents.
	switch {
	case path == "":
		return firstRuneToUpper(short)
	case short == "":
		return firstRuneToUpper(path)
	}
	// Godoc has special heurisitics to extract headers from the comments, from
	// which it builds a nice table of contents.  Headers must be single
	// unindented lines with unindented paragraphs both before and after, and the
	// line must not include certain characters.
	//
	// We try our best to create a header that includes both the command path and
	// the short description, but if godoc won't extract a header out of the line,
	// we fall back to just returning the command path.
	//
	// For more details see the comments and implementation of doc.ToHTML:
	// http://golang.org/pkg/go/doc/#ToHTML
	header := firstRuneToUpper(path + " - " + short)
	var buf bytes.Buffer
	doc.ToHTML(&buf, "before\n\n"+header+"\n\nafter", nil)
	if !bytes.Contains(buf.Bytes(), []byte("<h")) {
		return firstRuneToUpper(path)
	}
	return header
}

func firstRuneToUpper(s string) string {
	if s == "" {
		return ""
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToUpper(r)) + s[n:]
}

func lineBreak(w *textutil.LineWriter, style style) {
	w.Flush()
	switch style {
	case styleCompact, styleFull:
		width := w.Width()
		if width < 0 {
			// If the user has chosen an "unlimited" word-wrapping width, we still
			// need a reasonable width for our visual line break.
			width = defaultWidth
		}
		fmt.Fprintln(w, strings.Repeat("=", width))
	case styleGoDoc:
		fmt.Fprintln(w)
	}
	w.Flush()
}

// needsHelpChild returns true if cmd needs a default help command to be
// appended to its children.  Every command that has children and doesn't
// already have a "help" command needs a help child.
func needsHelpChild(cmd *Command) bool {
	for _, child := range cmd.Children {
		if child.Name == helpName {
			return false
		}
	}
	return len(cmd.Children) > 0
}

// usageAll prints usage recursively via DFS from the path onward.
func usageAll(w *textutil.LineWriter, env *Env, path []*Command, config *helpConfig, firstCall bool) {
	cmd, cmdPath := path[len(path)-1], pathName(config.prefix, path)
	usage(w, env, path, config, firstCall)
	for _, child := range cmd.Children {
		usageAll(w, env, append(path, child), config, false)
	}
	if firstCall && needsHelpChild(cmd) {
		help := helpRunner{path, config}.newCommand()
		usageAll(w, env, append(path, help), config, false)
	}
	if cmd.LookPath {
		extNames := lookPathAll(env, cmd.Name, cmd.subNames())
		for _, extName := range extNames {
			runner := binaryRunner{extName, cmdPath}
			var buffer bytes.Buffer
			envCopy := env.clone()
			envCopy.Stdout = &buffer
			envCopy.Stderr = &buffer
			envCopy.Vars["CMDLINE_FIRST_CALL"] = "false"
			envCopy.Vars["CMDLINE_STYLE"] = config.style.String()
			if err := runner.Run(envCopy, []string{helpName, "..."}); err == nil {
				// The external child supports "help".
				if config.style == styleGoDoc {
					// The textutil package will discard any leading empty lines
					// produced by the child process output, so we need to
					// output it here.
					fmt.Fprintln(w)
				}
				fmt.Fprint(w, buffer.String())
				continue
			}
			buffer.Reset()
			if err := runner.Run(envCopy, []string{"-help"}); err == nil {
				// The external child supports "-help".
				if config.style == styleGoDoc {
					// The textutil package will discard any leading empty lines
					// produced by the child process output, so we need to
					// output it here.
					fmt.Fprintln(w)
				}
				fmt.Fprint(w, buffer.String())
				continue
			}
			// The external child does not support "help" or "-help".
			lineBreak(w, config.style)
			fmt.Fprintln(w, godocHeader(cmdPath+" "+strings.TrimPrefix(extName, cmd.Name+"-"), missingDescription))
		}
	}
	for _, topic := range cmd.Topics {
		lineBreak(w, config.style)
		w.ForceVerbatim(true)
		fmt.Fprintln(w, godocHeader(cmdPath+" "+topic.Name, topic.Short))
		w.ForceVerbatim(false)
		fmt.Fprintln(w)
		fmt.Fprintln(w, topic.Long)
	}
}

// usage prints the usage of the last command in path to w.  The bool firstCall
// is set to false when printing usage for multiple commands, and is used to
// avoid printing redundant information (e.g. help command, global flags).
func usage(w *textutil.LineWriter, env *Env, path []*Command, config *helpConfig, firstCall bool) {
	cmd, cmdPath := path[len(path)-1], pathName(config.prefix, path)
	env.TimerPush("usage " + cmdPath)
	defer env.TimerPop()
	if config.style == styleShortOnly {
		fmt.Fprintln(w, cmd.Short)
		return
	}
	if !firstCall {
		lineBreak(w, config.style)
		w.ForceVerbatim(true)
		fmt.Fprintln(w, godocHeader(cmdPath, cmd.Short))
		w.ForceVerbatim(false)
		fmt.Fprintln(w)
	}
	fmt.Fprintln(w, cmd.Long)
	fmt.Fprintln(w)
	// Usage line.
	fmt.Fprintln(w, "Usage:")
	cmdPathF := "   " + cmdPath
	if countFlags(pathFlags(path), nil, true) > 0 || countFlags(globalFlags, nil, true) > 0 {
		cmdPathF += " [flags]"
	}
	if cmd.Runner != nil {
		if cmd.ArgsName != "" {
			fmt.Fprintln(w, cmdPathF, cmd.ArgsName)
		} else {
			fmt.Fprintln(w, cmdPathF)
		}
	}
	var extChildren []string
	if cmd.LookPath {
		extChildren = lookPathAll(env, cmd.Name, cmd.subNames())
	}
	hasSubcommands := len(cmd.Children) > 0 || len(extChildren) > 0
	if hasSubcommands {
		fmt.Fprintln(w, cmdPathF, "<command>")
		fmt.Fprintln(w)
	}
	printShort := func(width int, name, short string) {
		fmt.Fprintf(w, "%-[1]*[2]s %[3]s", width, name, short)
		w.Flush()
	}
	const minNameWidth = 11
	nameWidth := minNameWidth
	for _, child := range cmd.Children {
		if w := len(child.Name); w > nameWidth {
			nameWidth = w
		}
	}
	for _, ext := range extChildren {
		if w := len(strings.TrimPrefix(ext, cmd.Name+"-")); w > nameWidth {
			nameWidth = w
		}
	}
	// Built-in commands.
	if len(cmd.Children) > 0 {
		w.SetIndents()
		fmt.Fprintln(w, "The", cmdPath, "commands are:")
		// Print as a table with aligned columns Name and Short.
		w.SetIndents(spaces(3), spaces(3+nameWidth+1))
		for _, child := range cmd.Children {
			printShort(nameWidth, child.Name, child.Short)
		}
		// Default help command.
		if firstCall && needsHelpChild(cmd) {
			printShort(nameWidth, helpName, helpShort)
		}
	}
	// External commands.
	if len(extChildren) > 0 {
		w.SetIndents()
		fmt.Fprintln(w, "The", cmdPath, "external commands are:")
		// Print as a table with aligned columns Name and Short.
		w.SetIndents(spaces(3), spaces(3+nameWidth+1))
		for _, ext := range extChildren {
			runner := binaryRunner{ext, cmdPath}
			var buffer bytes.Buffer
			envCopy := env.clone()
			envCopy.Stdout = &buffer
			envCopy.Stderr = &buffer
			envCopy.Vars["CMDLINE_STYLE"] = "shortonly"
			short := missingDescription
			if err := runner.Run(envCopy, []string{"-help"}); err == nil {
				// The external child supports "-help".
				short = buffer.String()
			}
			printShort(nameWidth, strings.TrimPrefix(ext, cmd.Name+"-"), short)
		}
	}
	// Command footer.
	if hasSubcommands {
		w.SetIndents()
		if firstCall && config.style != styleGoDoc {
			fmt.Fprintf(w, "Run \"%s help [command]\" for command usage.\n", cmdPath)
		}
	}
	// Args.
	if cmd.Runner != nil && cmd.ArgsLong != "" {
		fmt.Fprintln(w)
		fmt.Fprintln(w, cmd.ArgsLong)
	}
	// Help topics.
	if len(cmd.Topics) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The", cmdPath, "additional help topics are:")
		nameWidth := minNameWidth
		for _, topic := range cmd.Topics {
			if w := len(topic.Name); w > nameWidth {
				nameWidth = w
			}
		}
		// Print as a table with aligned columns Name and Short.
		w.SetIndents(spaces(3), spaces(3+nameWidth+1))
		for _, topic := range cmd.Topics {
			printShort(nameWidth, topic.Name, topic.Short)
		}
		w.SetIndents()
		if firstCall && config.style != styleGoDoc {
			fmt.Fprintf(w, "Run \"%s help [topic]\" for topic details.\n", cmdPath)
		}
	}
	hidden := flagsUsage(w, path, config)
	// Only show global flags on the first call.
	if firstCall {
		hidden = globalFlagsUsage(w, config) || hidden
	}
	if hidden {
		fmt.Fprintln(w)
		fullhelp := fmt.Sprintf(`Run "%s help -style=full" to show all flags.`, cmdPath)
		if len(cmd.Children) == 0 {
			if len(path) > 1 {
				parentPath := pathName(config.prefix, path[:len(path)-1])
				fullhelp = fmt.Sprintf(`Run "%s help -style=full %s" to show all flags.`, parentPath, cmd.Name)
			} else {
				fullhelp = fmt.Sprintf(`Run "CMDLINE_STYLE=full %s -help" to show all flags.`, cmdPath)
			}
		}
		fmt.Fprintln(w, fullhelp)
	}
}

func flagsUsage(w *textutil.LineWriter, path []*Command, config *helpConfig) bool {
	cmd, cmdPath := path[len(path)-1], pathName(config.prefix, path)
	allFlags := pathFlags(path)
	numCompact := countFlags(&cmd.Flags, nil, true)
	numFull := countFlags(allFlags, nil, true) - numCompact
	if config.style == styleCompact {
		// Compact style, only show compact flags.
		if numCompact > 0 {
			fmt.Fprintln(w)
			fmt.Fprintln(w, "The", cmdPath, "flags are:")
			printFlags(w, &cmd.Flags, nil, config.style, nil, true)
		}
		return numFull > 0
	}
	// Non-compact style, always show all flags.
	if numCompact > 0 || numFull > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The", cmdPath, "flags are:")
		printFlags(w, &cmd.Flags, nil, config.style, nil, true)
		if numCompact > 0 && numFull > 0 {
			fmt.Fprintln(w)
		}
		printFlags(w, allFlags, &cmd.Flags, config.style, nil, true)
	}
	return false
}

func globalFlagsUsage(w *textutil.LineWriter, config *helpConfig) bool {
	numCompact := countFlags(globalFlags, nonHiddenGlobalFlags, true)
	numFull := countFlags(globalFlags, nonHiddenGlobalFlags, false)
	if config.style == styleCompact {
		// Compact style, only show compact flags.
		if numCompact > 0 {
			fmt.Fprintln(w)
			fmt.Fprintln(w, "The global flags are:")
			printFlags(w, globalFlags, nil, config.style, nonHiddenGlobalFlags, true)
		}
		return numFull > 0
	}
	// Non-compact style, always show all global flags.
	if numCompact > 0 || numFull > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The global flags are:")
		printFlags(w, globalFlags, nil, config.style, nonHiddenGlobalFlags, true)
		if numCompact > 0 && numFull > 0 {
			fmt.Fprintln(w)
		}
		printFlags(w, globalFlags, nil, config.style, nonHiddenGlobalFlags, false)
	}
	return false
}

func countFlags(flags *flag.FlagSet, regexps []*regexp.Regexp, match bool) (num int) {
	flags.VisitAll(func(f *flag.Flag) {
		if match == matchRegexps(regexps, f.Name) {
			num++
		}
	})
	return
}

func printFlags(w *textutil.LineWriter, flags, filter *flag.FlagSet, style style, regexps []*regexp.Regexp, match bool) {
	flags.VisitAll(func(f *flag.Flag) {
		if filter != nil && filter.Lookup(f.Name) != nil {
			return
		}
		if match != matchRegexps(regexps, f.Name) {
			return
		}
		value := f.Value.String()
		if style == styleGoDoc {
			// When using styleGoDoc we use the default value, so that e.g. regular
			// help will show "/usr/home/me/foo" while godoc will show "$HOME/foo".
			value = f.DefValue
		}
		fmt.Fprintf(w, " -%s=%v", f.Name, value)
		w.SetIndents(spaces(3))
		fmt.Fprintln(w, f.Usage)
		w.SetIndents()
	})
}

func spaces(count int) string {
	return strings.Repeat(" ", count)
}

func matchRegexps(regexps []*regexp.Regexp, name string) bool {
	// We distinguish nil regexps from empty regexps; the former means "all names
	// match", while the latter means "no names match".
	if regexps == nil {
		return true
	}
	for _, r := range regexps {
		if r.MatchString(name) {
			return true
		}
	}
	return false
}

var nonHiddenGlobalFlags []*regexp.Regexp

// HideGlobalFlagsExcept hides global flags from the default compact-style usage
// message, except for the given regexps.  Global flag names that match any of
// the regexps will still be shown in the compact usage message.  Multiple calls
// behave as if all regexps were provided in a single call.
//
// All global flags are always shown in non-compact style usage messages.
func HideGlobalFlagsExcept(regexps ...*regexp.Regexp) {
	// NOTE: nonHiddenGlobalFlags is used as the argument to matchRegexps, where
	// nil means "all names match" and empty means "no names match".
	nonHiddenGlobalFlags = append(nonHiddenGlobalFlags, regexps...)
	if nonHiddenGlobalFlags == nil {
		nonHiddenGlobalFlags = []*regexp.Regexp{}
	}
}
