// 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"
	"path/filepath"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"

	"go.fuchsia.dev/jiri/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.NewUTF8WrapWriter(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.NewUTF8WrapWriter(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.WrapWriter, 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.
		if subCmd, _ := env.LookPath(cmd.Name + "-" + subName); subCmd != "" {
			runner := binaryRunner{subCmd, 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.WrapWriter, 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.WrapWriter, 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 {
		cmdPrefix := cmd.Name + "-"
		subCmds, _ := env.LookPathPrefix(cmdPrefix, cmd.subNames(cmdPrefix))
		for _, subCmd := range subCmds {
			runner := binaryRunner{subCmd, 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)
			subName := strings.TrimPrefix(filepath.Base(subCmd), cmdPrefix)
			fmt.Fprintln(w, godocHeader(cmdPath+" "+subName, 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.WrapWriter, 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
	cmdPrefix := cmd.Name + "-"
	if cmd.LookPath {
		extChildren, _ = env.LookPathPrefix(cmdPrefix, cmd.subNames(cmdPrefix))
	}
	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 _, extCmd := range extChildren {
		extName := strings.TrimPrefix(filepath.Base(extCmd), cmdPrefix)
		if w := len(extName); 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 _, extCmd := range extChildren {
			runner := binaryRunner{extCmd, 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()
			}
			extName := strings.TrimPrefix(filepath.Base(extCmd), cmdPrefix)
			printShort(nameWidth, extName, 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.WrapWriter, 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.WrapWriter, config *helpConfig) bool {
	regex := regexp.MustCompilePOSIX("^test\\..*$")
	HideGlobalFlags(regex)
	numCompact := countFlags(globalFlags, hiddenGlobalFlags, false)
	numFull := countFlags(globalFlags, hiddenGlobalFlags, true)
	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, hiddenGlobalFlags, false)
		}
		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, hiddenGlobalFlags, false)
		if numCompact > 0 && numFull > 0 {
			fmt.Fprintln(w)
		}
		printFlags(w, globalFlags, nil, config.style, hiddenGlobalFlags, true)
	}
	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.WrapWriter, 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 hiddenGlobalFlags []*regexp.Regexp

// HideGlobalFlags hides global flags from the default compact-style usage
// message.  Global flag names that match any of the regexps will not 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 HideGlobalFlags(regexps ...*regexp.Regexp) {
	hiddenGlobalFlags = append(hiddenGlobalFlags, regexps...)
	if hiddenGlobalFlags == nil {
		hiddenGlobalFlags = []*regexp.Regexp{}
	}
}
