package flags

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"unicode/utf8"
)

type parseState struct {
	arg     string
	args    []string
	retargs []string
	err     error

	command *Command
	lookup  lookup
}

func (p *parseState) eof() bool {
	return len(p.args) == 0
}

func (p *parseState) pop() string {
	if p.eof() {
		return ""
	}

	p.arg = p.args[0]
	p.args = p.args[1:]

	return p.arg
}

func (p *parseState) peek() string {
	if p.eof() {
		return ""
	}

	return p.args[0]
}

func (p *parseState) checkRequired() error {
	required := p.lookup.required

	if len(required) == 0 {
		return nil
	}

	names := make([]string, 0, len(required))

	for k := range required {
		names = append(names, "`"+k.String()+"'")
	}

	var msg string

	if len(names) == 1 {
		msg = fmt.Sprintf("the required flag %s was not specified", names[0])
	} else {
		msg = fmt.Sprintf("the required flags %s and %s were not specified",
			strings.Join(names[:len(names)-1], ", "), names[len(names)-1])
	}

	p.err = newError(ErrRequired, msg)
	return p.err
}

func (p *parseState) estimateCommand() error {
	commands := p.command.sortedCommands()
	cmdnames := make([]string, len(commands))

	for i, v := range commands {
		cmdnames[i] = v.Name
	}

	var msg string

	if len(p.retargs) != 0 {
		c, l := closestChoice(p.retargs[0], cmdnames)
		msg = fmt.Sprintf("Unknown command `%s'", p.retargs[0])

		if float32(l)/float32(len(c)) < 0.5 {
			msg = fmt.Sprintf("%s, did you mean `%s'?", msg, c)
		} else if len(cmdnames) == 1 {
			msg = fmt.Sprintf("%s. You should use the %s command",
				msg,
				cmdnames[0])
		} else {
			msg = fmt.Sprintf("%s. Please specify one command of: %s or %s",
				msg,
				strings.Join(cmdnames[:len(cmdnames)-1], ", "),
				cmdnames[len(cmdnames)-1])
		}
	} else {
		if len(cmdnames) == 1 {
			msg = fmt.Sprintf("Please specify the %s command", cmdnames[0])
		} else {
			msg = fmt.Sprintf("Please specify one command of: %s or %s",
				strings.Join(cmdnames[:len(cmdnames)-1], ", "),
				cmdnames[len(cmdnames)-1])
		}
	}

	return newError(ErrCommandRequired, msg)
}

func (p *Parser) parseOption(s *parseState, name string, option *Option, canarg bool, argument *string) (retoption *Option, err error) {
	if !option.canArgument() {
		if argument != nil {
			msg := fmt.Sprintf("bool flag `%s' cannot have an argument", option)
			return option, newError(ErrNoArgumentForBool, msg)
		}

		err = option.set(nil)
	} else if argument != nil {
		err = option.set(argument)
	} else if canarg && !s.eof() {
		arg := s.pop()
		err = option.set(&arg)
	} else if option.OptionalArgument {
		option.clear()

		for _, v := range option.OptionalValue {
			err = option.set(&v)

			if err != nil {
				break
			}
		}
	} else {
		msg := fmt.Sprintf("expected argument for flag `%s'", option)
		err = newError(ErrExpectedArgument, msg)
	}

	if err != nil {
		if _, ok := err.(*Error); !ok {
			msg := fmt.Sprintf("invalid argument for flag `%s' (expected %s): %s",
				option,
				option.value.Type(),
				err.Error())

			err = newError(ErrMarshal, msg)
		}
	}

	return option, err
}

func (p *Parser) parseLong(s *parseState, name string, argument *string) (option *Option, err error) {
	if option := s.lookup.longNames[name]; option != nil {
		// Only long options that are required can consume an argument
		// from the argument list
		canarg := !option.OptionalArgument

		return p.parseOption(s, name, option, canarg, argument)
	}

	return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", name))
}

func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) {
	c, n := utf8.DecodeRuneInString(optname)

	if n == len(optname) {
		return optname, nil
	}

	first := string(c)

	if option := s.lookup.shortNames[first]; option != nil && option.canArgument() {
		arg := optname[n:]
		return first, &arg
	}

	return optname, nil
}

func (p *Parser) parseShort(s *parseState, optname string, argument *string) (option *Option, err error) {
	if argument == nil {
		optname, argument = p.splitShortConcatArg(s, optname)
	}

	for i, c := range optname {
		shortname := string(c)

		if option = s.lookup.shortNames[shortname]; option != nil {
			// Only the last short argument can consume an argument from
			// the arguments list, and only if it's non optional
			canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument

			if _, err := p.parseOption(s, shortname, option, canarg, argument); err != nil {
				return option, err
			}
		} else {
			return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", shortname))
		}

		// Only the first option can have a concatted argument, so just
		// clear argument here
		argument = nil
	}

	return option, nil
}

func (p *Parser) parseNonOption(s *parseState) error {
	if cmd := s.lookup.commands[s.arg]; cmd != nil {
		if err := s.checkRequired(); err != nil {
			return err
		}

		s.command.Active = cmd

		s.command = cmd
		s.lookup = cmd.makeLookup()
	} else if (p.Options & PassAfterNonOption) != None {
		// If PassAfterNonOption is set then all remaining arguments
		// are considered positional
		s.retargs = append(append(s.retargs, s.arg), s.args...)
		s.args = []string{}
	} else {
		s.retargs = append(s.retargs, s.arg)
	}

	return nil
}

func (p *Parser) showBuiltinHelp() error {
	var b bytes.Buffer

	p.WriteHelp(&b)
	return newError(ErrHelp, b.String())
}

func (p *Parser) printError(err error) error {
	if err != nil && (p.Options&PrintErrors) != None {
		fmt.Fprintln(os.Stderr, err)
	}

	return err
}
