package flags

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

// Option flag information. Contains a description of the option, short and
// long name as well as a default value and whether an argument for this
// flag is optional.
type Option struct {
	// The description of the option flag. This description is shown
	// automatically in the built-in help.
	Description string

	// The short name of the option (a single character). If not 0, the
	// option flag can be 'activated' using -<ShortName>. Either ShortName
	// or LongName needs to be non-empty.
	ShortName rune

	// The long name of the option. If not "", the option flag can be
	// activated using --<LongName>. Either ShortName or LongName needs
	// to be non-empty.
	LongName string

	// The default value of the option.
	Default []string

	// The optional environment default value key name.
	EnvDefaultKey string

	// The optional delimiter string for EnvDefaultKey values.
	EnvDefaultDelim string

	// If true, specifies that the argument to an option flag is optional.
	// When no argument to the flag is specified on the command line, the
	// value of OptionalValue will be set in the field this option represents.
	// This is only valid for non-boolean options.
	OptionalArgument bool

	// The optional value of the option. The optional value is used when
	// the option flag is marked as having an OptionalArgument. This means
	// that when the flag is specified, but no option argument is given,
	// the value of the field this option represents will be set to
	// OptionalValue. This is only valid for non-boolean options.
	OptionalValue []string

	// If true, the option _must_ be specified on the command line. If the
	// option is not specified, the parser will generate an ErrRequired type
	// error.
	Required bool

	// A name for the value of an option shown in the Help as --flag [ValueName]
	ValueName string

	// A mask value to show in the help instead of the default value. This
	// is useful for hiding sensitive information in the help, such as
	// passwords.
	DefaultMask string

	// If non empty, only a certain set of values is allowed for an option.
	Choices []string

	// If true, the option is not displayed in the help or man page
	Hidden bool

	// The group which the option belongs to
	group *Group

	// The struct field which the option represents.
	field reflect.StructField

	// The struct field value which the option represents.
	value reflect.Value

	// Determines if the option will be always quoted in the INI output
	iniQuote bool

	tag                     multiTag
	isSet                   bool
	isSetDefault            bool
	preventDefault          bool
	clearReferenceBeforeSet bool

	defaultLiteral string
}

// LongNameWithNamespace returns the option's long name with the group namespaces
// prepended by walking up the option's group tree. Namespaces and the long name
// itself are separated by the parser's namespace delimiter. If the long name is
// empty an empty string is returned.
func (option *Option) LongNameWithNamespace() string {
	if len(option.LongName) == 0 {
		return ""
	}

	// fetch the namespace delimiter from the parser which is always at the
	// end of the group hierarchy
	namespaceDelimiter := ""
	g := option.group

	for {
		if p, ok := g.parent.(*Parser); ok {
			namespaceDelimiter = p.NamespaceDelimiter

			break
		}

		switch i := g.parent.(type) {
		case *Command:
			g = i.Group
		case *Group:
			g = i
		}
	}

	// concatenate long name with namespace
	longName := option.LongName
	g = option.group

	for g != nil {
		if g.Namespace != "" {
			longName = g.Namespace + namespaceDelimiter + longName
		}

		switch i := g.parent.(type) {
		case *Command:
			g = i.Group
		case *Group:
			g = i
		case *Parser:
			g = nil
		}
	}

	return longName
}

// EnvKeyWithNamespace returns the option's env key with the group namespaces
// prepended by walking up the option's group tree. Namespaces and the env key
// itself are separated by the parser's namespace delimiter. If the env key is
// empty an empty string is returned.
func (option *Option) EnvKeyWithNamespace() string {
	if len(option.EnvDefaultKey) == 0 {
		return ""
	}

	// fetch the namespace delimiter from the parser which is always at the
	// end of the group hierarchy
	namespaceDelimiter := ""
	g := option.group

	for {
		if p, ok := g.parent.(*Parser); ok {
			namespaceDelimiter = p.EnvNamespaceDelimiter

			break
		}

		switch i := g.parent.(type) {
		case *Command:
			g = i.Group
		case *Group:
			g = i
		}
	}

	// concatenate long name with namespace
	key := option.EnvDefaultKey
	g = option.group

	for g != nil {
		if g.EnvNamespace != "" {
			key = g.EnvNamespace + namespaceDelimiter + key
		}

		switch i := g.parent.(type) {
		case *Command:
			g = i.Group
		case *Group:
			g = i
		case *Parser:
			g = nil
		}
	}

	return key
}

// String converts an option to a human friendly readable string describing the
// option.
func (option *Option) String() string {
	var s string
	var short string

	if option.ShortName != 0 {
		data := make([]byte, utf8.RuneLen(option.ShortName))
		utf8.EncodeRune(data, option.ShortName)
		short = string(data)

		if len(option.LongName) != 0 {
			s = fmt.Sprintf("%s%s, %s%s",
				string(defaultShortOptDelimiter), short,
				defaultLongOptDelimiter, option.LongNameWithNamespace())
		} else {
			s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short)
		}
	} else if len(option.LongName) != 0 {
		s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace())
	}

	return s
}

// Value returns the option value as an interface{}.
func (option *Option) Value() interface{} {
	return option.value.Interface()
}

// Field returns the reflect struct field of the option.
func (option *Option) Field() reflect.StructField {
	return option.field
}

// IsSet returns true if option has been set
func (option *Option) IsSet() bool {
	return option.isSet
}

// IsSetDefault returns true if option has been set via the default option tag
func (option *Option) IsSetDefault() bool {
	return option.isSetDefault
}

// Set the value of an option to the specified value. An error will be returned
// if the specified value could not be converted to the corresponding option
// value type.
func (option *Option) set(value *string) error {
	kind := option.value.Type().Kind()

	if (kind == reflect.Map || kind == reflect.Slice) && option.clearReferenceBeforeSet {
		option.empty()
	}

	option.isSet = true
	option.preventDefault = true
	option.clearReferenceBeforeSet = false

	if len(option.Choices) != 0 {
		found := false

		for _, choice := range option.Choices {
			if choice == *value {
				found = true
				break
			}
		}

		if !found {
			allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ")

			if len(option.Choices) > 1 {
				allowed += " or " + option.Choices[len(option.Choices)-1]
			}

			return newErrorf(ErrInvalidChoice,
				"Invalid value `%s' for option `%s'. Allowed values are: %s",
				*value, option, allowed)
		}
	}

	if option.isFunc() {
		return option.call(value)
	} else if value != nil {
		return convert(*value, option.value, option.tag)
	}

	return convert("", option.value, option.tag)
}

func (option *Option) setDefault(value *string) error {
	if option.preventDefault {
		return nil
	}

	if err := option.set(value); err != nil {
		return err
	}

	option.isSetDefault = true
	option.preventDefault = false

	return nil
}

func (option *Option) showInHelp() bool {
	return !option.Hidden && (option.ShortName != 0 || len(option.LongName) != 0)
}

func (option *Option) canArgument() bool {
	if u := option.isUnmarshaler(); u != nil {
		return true
	}

	return !option.isBool()
}

func (option *Option) emptyValue() reflect.Value {
	tp := option.value.Type()

	if tp.Kind() == reflect.Map {
		return reflect.MakeMap(tp)
	}

	return reflect.Zero(tp)
}

func (option *Option) empty() {
	if !option.isFunc() {
		option.value.Set(option.emptyValue())
	}
}

func (option *Option) clearDefault() error {
	if option.preventDefault {
		return nil
	}

	usedDefault := option.Default

	if envKey := option.EnvKeyWithNamespace(); envKey != "" {
		if value, ok := os.LookupEnv(envKey); ok {
			if option.EnvDefaultDelim != "" {
				usedDefault = strings.Split(value, option.EnvDefaultDelim)
			} else {
				usedDefault = []string{value}
			}
		}
	}

	option.isSetDefault = true

	if len(usedDefault) > 0 {
		option.empty()

		for _, d := range usedDefault {
			err := option.setDefault(&d)

			if err != nil {
				return err
			}
		}
	} else {
		tp := option.value.Type()

		switch tp.Kind() {
		case reflect.Map:
			if option.value.IsNil() {
				option.empty()
			}
		case reflect.Slice:
			if option.value.IsNil() {
				option.empty()
			}
		}
	}

	return nil
}

func (option *Option) valueIsDefault() bool {
	// Check if the value of the option corresponds to its
	// default value
	emptyval := option.emptyValue()

	checkvalptr := reflect.New(emptyval.Type())
	checkval := reflect.Indirect(checkvalptr)

	checkval.Set(emptyval)

	if len(option.Default) != 0 {
		for _, v := range option.Default {
			convert(v, checkval, option.tag)
		}
	}

	return reflect.DeepEqual(option.value.Interface(), checkval.Interface())
}

func (option *Option) isUnmarshaler() Unmarshaler {
	v := option.value

	for {
		if !v.CanInterface() {
			break
		}

		i := v.Interface()

		if u, ok := i.(Unmarshaler); ok {
			return u
		}

		if !v.CanAddr() {
			break
		}

		v = v.Addr()
	}

	return nil
}

func (option *Option) isValueValidator() ValueValidator {
	v := option.value

	for {
		if !v.CanInterface() {
			break
		}

		i := v.Interface()

		if u, ok := i.(ValueValidator); ok {
			return u
		}

		if !v.CanAddr() {
			break
		}

		v = v.Addr()
	}

	return nil
}

func (option *Option) isBool() bool {
	tp := option.value.Type()

	for {
		switch tp.Kind() {
		case reflect.Slice, reflect.Ptr:
			tp = tp.Elem()
		case reflect.Bool:
			return true
		case reflect.Func:
			return tp.NumIn() == 0
		default:
			return false
		}
	}
}

func (option *Option) isSignedNumber() bool {
	tp := option.value.Type()

	for {
		switch tp.Kind() {
		case reflect.Slice, reflect.Ptr:
			tp = tp.Elem()
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
			return true
		default:
			return false
		}
	}
}

func (option *Option) isFunc() bool {
	return option.value.Type().Kind() == reflect.Func
}

func (option *Option) call(value *string) error {
	var retval []reflect.Value

	if value == nil {
		retval = option.value.Call(nil)
	} else {
		tp := option.value.Type().In(0)

		val := reflect.New(tp)
		val = reflect.Indirect(val)

		if err := convert(*value, val, option.tag); err != nil {
			return err
		}

		retval = option.value.Call([]reflect.Value{val})
	}

	if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() {
		if retval[0].Interface() == nil {
			return nil
		}

		return retval[0].Interface().(error)
	}

	return nil
}

func (option *Option) updateDefaultLiteral() {
	defs := option.Default
	def := ""

	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 {
		l := len(defs) - 1

		for i := 0; i < l; i++ {
			def += quoteIfNeeded(defs[i]) + ", "
		}

		def += quoteIfNeeded(defs[l])
	}

	option.defaultLiteral = def
}

func (option *Option) shortAndLongName() string {
	ret := &bytes.Buffer{}

	if option.ShortName != 0 {
		ret.WriteRune(defaultShortOptDelimiter)
		ret.WriteRune(option.ShortName)
	}

	if len(option.LongName) != 0 {
		if option.ShortName != 0 {
			ret.WriteRune('/')
		}

		ret.WriteString(option.LongName)
	}

	return ret.String()
}

func (option *Option) isValidValue(arg string) error {
	if validator := option.isValueValidator(); validator != nil {
		return validator.IsValidValue(arg)
	}
	if argumentIsOption(arg) && !(option.isSignedNumber() && len(arg) > 1 && arg[0] == '-' && arg[1] >= '0' && arg[1] <= '9') {
		return fmt.Errorf("expected argument for flag `%s', but got option `%s'", option, arg)
	}
	return nil
}
