package flags

import (
	"bytes"
	"fmt"
	"reflect"
	"strings"
	"syscall"
	"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

	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
}

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

// 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.isSet {
		option.empty()
	}

	option.isSet = true
	option.preventDefault = true

	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) canCli() bool {
	return 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() {
	usedDefault := option.Default

	if envKey := option.EnvDefaultKey; envKey != "" {
		// os.Getenv() makes no distinction between undefined and
		// empty values, so we use syscall.Getenv()
		if value, ok := syscall.Getenv(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 {
			option.set(&d)
			option.isSetDefault = true
		}
	} 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()
			}
		}
	}
}

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) 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()
}
