package instructions

import (
	"fmt"
	"strings"
)

// FlagType is the type of the build flag
type FlagType int

const (
	boolType FlagType = iota
	stringType
)

// BFlags contains all flags information for the builder
type BFlags struct {
	Args  []string // actual flags/args from cmd line
	flags map[string]*Flag
	used  map[string]*Flag
	Err   error
}

// Flag contains all information for a flag
type Flag struct {
	bf       *BFlags
	name     string
	flagType FlagType
	Value    string
}

// NewBFlags returns the new BFlags struct
func NewBFlags() *BFlags {
	return &BFlags{
		flags: make(map[string]*Flag),
		used:  make(map[string]*Flag),
	}
}

// NewBFlagsWithArgs returns the new BFlags struct with Args set to args
func NewBFlagsWithArgs(args []string) *BFlags {
	flags := NewBFlags()
	flags.Args = args
	return flags
}

// AddBool adds a bool flag to BFlags
// Note, any error will be generated when Parse() is called (see Parse).
func (bf *BFlags) AddBool(name string, def bool) *Flag {
	flag := bf.addFlag(name, boolType)
	if flag == nil {
		return nil
	}
	if def {
		flag.Value = "true"
	} else {
		flag.Value = "false"
	}
	return flag
}

// AddString adds a string flag to BFlags
// Note, any error will be generated when Parse() is called (see Parse).
func (bf *BFlags) AddString(name string, def string) *Flag {
	flag := bf.addFlag(name, stringType)
	if flag == nil {
		return nil
	}
	flag.Value = def
	return flag
}

// addFlag is a generic func used by the other AddXXX() func
// to add a new flag to the BFlags struct.
// Note, any error will be generated when Parse() is called (see Parse).
func (bf *BFlags) addFlag(name string, flagType FlagType) *Flag {
	if _, ok := bf.flags[name]; ok {
		bf.Err = fmt.Errorf("Duplicate flag defined: %s", name)
		return nil
	}

	newFlag := &Flag{
		bf:       bf,
		name:     name,
		flagType: flagType,
	}
	bf.flags[name] = newFlag

	return newFlag
}

// IsUsed checks if the flag is used
func (fl *Flag) IsUsed() bool {
	if _, ok := fl.bf.used[fl.name]; ok {
		return true
	}
	return false
}

// IsTrue checks if a bool flag is true
func (fl *Flag) IsTrue() bool {
	if fl.flagType != boolType {
		// Should never get here
		panic(fmt.Errorf("Trying to use IsTrue on a non-boolean: %s", fl.name))
	}
	return fl.Value == "true"
}

// Parse parses and checks if the BFlags is valid.
// Any error noticed during the AddXXX() funcs will be generated/returned
// here.  We do this because an error during AddXXX() is more like a
// compile time error so it doesn't matter too much when we stop our
// processing as long as we do stop it, so this allows the code
// around AddXXX() to be just:
//     defFlag := AddString("description", "")
// w/o needing to add an if-statement around each one.
func (bf *BFlags) Parse() error {
	// If there was an error while defining the possible flags
	// go ahead and bubble it back up here since we didn't do it
	// earlier in the processing
	if bf.Err != nil {
		return fmt.Errorf("Error setting up flags: %s", bf.Err)
	}

	for _, arg := range bf.Args {
		if !strings.HasPrefix(arg, "--") {
			return fmt.Errorf("Arg should start with -- : %s", arg)
		}

		if arg == "--" {
			return nil
		}

		arg = arg[2:]
		value := ""

		index := strings.Index(arg, "=")
		if index >= 0 {
			value = arg[index+1:]
			arg = arg[:index]
		}

		flag, ok := bf.flags[arg]
		if !ok {
			return fmt.Errorf("Unknown flag: %s", arg)
		}

		if _, ok = bf.used[arg]; ok {
			return fmt.Errorf("Duplicate flag specified: %s", arg)
		}

		bf.used[arg] = flag

		switch flag.flagType {
		case boolType:
			// value == "" is only ok if no "=" was specified
			if index >= 0 && value == "" {
				return fmt.Errorf("Missing a value on flag: %s", arg)
			}

			lower := strings.ToLower(value)
			if lower == "" {
				flag.Value = "true"
			} else if lower == "true" || lower == "false" {
				flag.Value = lower
			} else {
				return fmt.Errorf("Expecting boolean value for flag %s, not: %s", arg, value)
			}

		case stringType:
			if index < 0 {
				return fmt.Errorf("Missing a value on flag: %s", arg)
			}
			flag.Value = value

		default:
			panic("No idea what kind of flag we have! Should never get here!")
		}

	}

	return nil
}
