// 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 (
	"flag"
	"fmt"
	"io"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"

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

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

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

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

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

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

const helpName = "help"

// newCommand returns a new help command that uses h as its Runner.
func (h helpRunner) newCommand() *Command {
	help := &Command{
		Runner: h,
		Name:   helpName,
		Short:  "Display help for commands or topics",
		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.
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, stderr io.Writer, args []string, path []*Command, config *helpConfig) error {
	if len(args) == 0 {
		usage(w, path, config, true)
		return nil
	}
	if args[0] == "..." {
		usageAll(w, path, config, true)
		return nil
	}
	// Look for matching children.
	cmd, subName, subArgs := path[len(path)-1], args[0], args[1:]
	for _, child := range cmd.Children {
		if child.Name == subName {
			return runHelp(w, stderr, subArgs, append(path, child), config)
		}
	}
	if helpName == subName {
		help := helpRunner{path, config}.newCommand()
		return runHelp(w, stderr, subArgs, append(path, help), config)
	}
	// 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(stderr, fn, "%s: unknown command or topic %q", pathName(path), subName)
}

func godocHeader(s 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.
	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, path []*Command, config *helpConfig, firstCall bool) {
	cmd, cmdPath := path[len(path)-1], pathName(path)
	if !firstCall {
		lineBreak(w, config.style)
		fmt.Fprintln(w, godocHeader(cmdPath))
		fmt.Fprintln(w)
	}
	usage(w, path, config, firstCall)
	for _, child := range cmd.Children {
		usageAll(w, append(path, child), config, false)
	}
	if firstCall && needsHelpChild(cmd) {
		help := helpRunner{path, config}.newCommand()
		usageAll(w, append(path, help), config, false)
	}
	for _, topic := range cmd.Topics {
		lineBreak(w, config.style)
		fmt.Fprintln(w, godocHeader(cmdPath+" "+topic.Name+" - help topic"))
		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, path []*Command, config *helpConfig, firstCall bool) {
	cmd, cmdPath := path[len(path)-1], pathName(path)
	children := cmd.Children
	if firstCall && needsHelpChild(cmd) {
		help := helpRunner{path, config}.newCommand()
		children = append(children, help)
	}
	fmt.Fprintln(w, cmd.Long)
	fmt.Fprintln(w)
	// Usage line.
	fmt.Fprintln(w, "Usage:")
	cmdPathF := "   " + cmdPath
	if countFlags(&cmd.Flags, nil, true) > 0 {
		cmdPathF += " [flags]"
	}
	if cmd.Runner != nil {
		if cmd.ArgsName != "" {
			fmt.Fprintln(w, cmdPathF, cmd.ArgsName)
		} else {
			fmt.Fprintln(w, cmdPathF)
		}
	}
	if len(children) > 0 {
		fmt.Fprintln(w, cmdPathF, "<command>")
	}
	// Commands.
	const minNameWidth = 11
	if len(children) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The", cmdPath, "commands are:")
		nameWidth := minNameWidth
		for _, child := range children {
			if len(child.Name) > nameWidth {
				nameWidth = len(child.Name)
			}
		}
		// Print as a table with aligned columns Name and Short.
		w.SetIndents(spaces(3), spaces(3+nameWidth+1))
		for _, child := range children {
			fmt.Fprintf(w, "%-[1]*[2]s %[3]s", nameWidth, child.Name, child.Short)
			w.Flush()
		}
		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 len(topic.Name) > nameWidth {
				nameWidth = len(topic.Name)
			}
		}
		// Print as a table with aligned columns Name and Short.
		w.SetIndents(spaces(3), spaces(3+nameWidth+1))
		for _, topic := range cmd.Topics {
			fmt.Fprintf(w, "%-[1]*[2]s %[3]s", nameWidth, topic.Name, topic.Short)
			w.Flush()
		}
		w.SetIndents()
		if firstCall && config.style != styleGoDoc {
			fmt.Fprintf(w, "Run \"%s help [topic]\" for topic details.\n", cmdPath)
		}
	}
	flagsUsage(w, path, config, firstCall)
}

func flagsUsage(w *textutil.LineWriter, path []*Command, config *helpConfig, firstCall bool) {
	cmd, cmdPath := path[len(path)-1], pathName(path)
	// Flags.
	if countFlags(&cmd.Flags, nil, true) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The", cmdPath, "flags are:")
		printFlags(w, &cmd.Flags, config.style, nil, true)
	}
	// Only show global flags on the first call.
	if !firstCall {
		return
	}
	hasCompact := countFlags(globalFlags, nonHiddenGlobalFlags, true) > 0
	hasFull := countFlags(globalFlags, nonHiddenGlobalFlags, false) > 0
	if config.style != styleCompact {
		// Non-compact style, always show all global flags.
		if hasCompact || hasFull {
			fmt.Fprintln(w)
			fmt.Fprintln(w, "The global flags are:")
			printFlags(w, globalFlags, config.style, nonHiddenGlobalFlags, true)
			if hasCompact && hasFull {
				fmt.Fprintln(w)
			}
			printFlags(w, globalFlags, config.style, nonHiddenGlobalFlags, false)
		}
		return
	}
	// Compact style, only show compact flags and a reminder if there are more.
	if hasCompact {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "The global flags are:")
		printFlags(w, globalFlags, config.style, nonHiddenGlobalFlags, true)
	}
	if hasFull {
		fmt.Fprintln(w)
		fullhelp := fmt.Sprintf(`Run "%s help -style=full" to show all global flags.`, cmdPath)
		if len(cmd.Children) == 0 {
			if len(path) > 1 {
				parentPath := pathName(path[:len(path)-1])
				fullhelp = fmt.Sprintf(`Run "%s help -style=full %s" to show all global flags.`, parentPath, cmd.Name)
			} else {
				fullhelp = fmt.Sprintf(`Run "CMDLINE_STYLE=full %s -help" to show all global flags.`, cmdPath)
			}
		}
		fmt.Fprintln(w, fullhelp)
	}
}

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 *flag.FlagSet, style style, regexps []*regexp.Regexp, match bool) {
	flags.VisitAll(func(f *flag.Flag) {
		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{}
	}
}
