// Copyright 2012 Jesse van den Kieboom. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package flags

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strings"
	"unicode/utf8"
)

type alignmentInfo struct {
	maxLongLen      int
	hasShort        bool
	hasValueName    bool
	terminalColumns int
	indent          bool
}

func (p *Parser) getAlignmentInfo() alignmentInfo {
	ret := alignmentInfo{
		maxLongLen:      0,
		hasShort:        false,
		hasValueName:    false,
		terminalColumns: getTerminalColumns(),
	}

	if ret.terminalColumns <= 0 {
		ret.terminalColumns = 80
	}

	p.eachActiveGroup(func(c *Command, grp *Group) {
		for _, info := range grp.options {
			if !info.canCli() {
				continue
			}

			if info.ShortName != 0 {
				ret.hasShort = true
			}

			lv := utf8.RuneCountInString(info.ValueName)

			if lv != 0 {
				ret.hasValueName = true
			}

			l := utf8.RuneCountInString(info.LongName) + lv

			if c != p.Command {
				// for indenting
				l = l + 4
			}

			if l > ret.maxLongLen {
				ret.maxLongLen = l
			}
		}
	})

	return ret
}

func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
	line := &bytes.Buffer{}

	distanceBetweenOptionAndDescription := 2
	paddingBeforeOption := 2

	prefix := paddingBeforeOption

	if info.indent {
		prefix += 4
	}

	line.WriteString(strings.Repeat(" ", prefix))

	if option.ShortName != 0 {
		line.WriteRune(defaultShortOptDelimiter)
		line.WriteRune(option.ShortName)
	} else if info.hasShort {
		line.WriteString("  ")
	}

	descstart := info.maxLongLen + paddingBeforeOption + distanceBetweenOptionAndDescription

	if info.hasShort {
		descstart += 2
	}

	if info.maxLongLen > 0 {
		descstart += 4
	}

	if info.hasValueName {
		descstart += 3
	}

	if len(option.LongName) > 0 {
		if option.ShortName != 0 {
			line.WriteString(", ")
		} else if info.hasShort {
			line.WriteString("  ")
		}

		line.WriteString(defaultLongOptDelimiter)
		line.WriteString(option.LongName)
	}

	if option.canArgument() {
		line.WriteRune(defaultNameArgDelimiter)

		if len(option.ValueName) > 0 {
			line.WriteString(option.ValueName)
		}
	}

	written := line.Len()
	line.WriteTo(writer)

	if option.Description != "" {
		dw := descstart - written
		writer.WriteString(strings.Repeat(" ", dw))

		def := ""
		defs := option.Default

		if len(option.DefaultMask) != 0 {
			if option.DefaultMask != "-" {
				def = option.DefaultMask
			}
		} else if len(defs) == 0 && option.canArgument() {
			var showdef bool

			switch option.field.Type.Kind() {
			case reflect.Func, reflect.Ptr:
				showdef = !option.value.IsNil()
			case reflect.Slice, reflect.String, reflect.Array:
				showdef = option.value.Len() > 0
			case reflect.Map:
				showdef = !option.value.IsNil() && option.value.Len() > 0
			default:
				zeroval := reflect.Zero(option.field.Type)
				showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface())
			}

			if showdef {
				def, _ = convertToString(option.value, option.tag)
			}
		} else if len(defs) != 0 {
			def = strings.Join(defs, ", ")
		}

		var desc string

		if def != "" {
			desc = fmt.Sprintf("%s (%v)", option.Description, def)
		} else {
			desc = option.Description
		}

		writer.WriteString(wrapText(desc,
			info.terminalColumns-descstart,
			strings.Repeat(" ", descstart)))
	}

	writer.WriteString("\n")
}

func maxCommandLength(s []*Command) int {
	if len(s) == 0 {
		return 0
	}

	ret := len(s[0].Name)

	for _, v := range s[1:] {
		l := len(v.Name)

		if l > ret {
			ret = l
		}
	}

	return ret
}

// WriteHelp writes a help message containing all the possible options and
// their descriptions to the provided writer. Note that the HelpFlag parser
// option provides a convenient way to add a -h/--help option group to the
// command line parser which will automatically show the help messages using
// this method.
func (p *Parser) WriteHelp(writer io.Writer) {
	if writer == nil {
		return
	}

	wr := bufio.NewWriter(writer)
	aligninfo := p.getAlignmentInfo()

	cmd := p.Command

	for cmd.Active != nil {
		cmd = cmd.Active
	}

	if p.Name != "" {
		wr.WriteString("Usage:\n")
		wr.WriteString(" ")

		allcmd := p.Command

		for allcmd != nil {
			var usage string

			if allcmd == p.Command {
				if len(p.Usage) != 0 {
					usage = p.Usage
				} else if p.Options&HelpFlag != 0 {
					usage = "[OPTIONS]"
				}
			} else if us, ok := allcmd.data.(Usage); ok {
				usage = us.Usage()
			} else if allcmd.hasCliOptions() {
				usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name)
			}

			if len(usage) != 0 {
				fmt.Fprintf(wr, " %s %s", allcmd.Name, usage)
			} else {
				fmt.Fprintf(wr, " %s", allcmd.Name)
			}

			if allcmd.Active == nil && len(allcmd.commands) > 0 {
				var co, cc string

				if allcmd.SubcommandsOptional {
					co, cc = "[", "]"
				} else {
					co, cc = "<", ">"
				}

				if len(allcmd.commands) > 3 {
					fmt.Fprintf(wr, " %scommand%s", co, cc)
				} else {
					subcommands := allcmd.sortedCommands()
					names := make([]string, len(subcommands))

					for i, subc := range subcommands {
						names[i] = subc.Name
					}

					fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc)
				}
			}

			allcmd = allcmd.Active
		}

		fmt.Fprintln(wr)

		if len(cmd.LongDescription) != 0 {
			fmt.Fprintln(wr)

			t := wrapText(cmd.LongDescription,
				aligninfo.terminalColumns,
				"")

			fmt.Fprintln(wr, t)
		}
	}

	prevcmd := p.Command

	p.eachActiveGroup(func(c *Command, grp *Group) {
		first := true

		// Skip built-in help group for all commands except the top-level
		// parser
		if grp.isBuiltinHelp && c != p.Command {
			return
		}

		for _, info := range grp.options {
			if info.canCli() {
				if prevcmd != c {
					fmt.Fprintf(wr, "\n[%s command options]\n", c.Name)
					prevcmd = c
					aligninfo.indent = true
				}

				if first && prevcmd.Group != grp {
					fmt.Fprintln(wr)

					if aligninfo.indent {
						wr.WriteString("    ")
					}

					fmt.Fprintf(wr, "%s:\n", grp.ShortDescription)
					first = false
				}

				p.writeHelpOption(wr, info, aligninfo)
			}
		}
	})

	scommands := cmd.sortedCommands()

	if len(scommands) > 0 {
		maxnamelen := maxCommandLength(scommands)

		fmt.Fprintln(wr)
		fmt.Fprintln(wr, "Available commands:")

		for _, c := range scommands {
			fmt.Fprintf(wr, "  %s", c.Name)

			if len(c.ShortDescription) > 0 {
				pad := strings.Repeat(" ", maxnamelen-len(c.Name))
				fmt.Fprintf(wr, "%s  %s", pad, c.ShortDescription)

				if len(c.Aliases) > 0 {
					fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", "))
				}

			}

			fmt.Fprintln(wr)
		}
	}

	wr.Flush()
}
