func envToFlag(e string) string {
	return strings.Replace(strings.ToLower(e), "_", "-", -1)
}
envToFlag converts THIS_FORMAT to this-format
package envflag
import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
)
var (
	debugEnabled = false
)
type EnvFlag struct {
	flagSet           *flag.FlagSet      
	minLength         int                
	envFlagDict       map[string]string  
	showEnvKeyInUsage bool               
	showEnvValInUsage bool               
}
func (ef EnvFlag) ProcessFlagWithEnv() error {
	if ef.flagSet.Parsed() {
		return errors.New("flag has already been parsed")
	}
	flagEnvMap := map[string]string{}
	for k, v := range ef.envFlagDict {
		flagEnvMap[v] = k
	}
	if ef.showEnvKeyInUsage {
		ef.flagSet.VisitAll(func(f *flag.Flag) {
			if len(f.Name) < ef.minLength {
				return
			}
			envKey, ok := flagEnvMap[f.Name]
			if !ok {
				envKey = flagToEnv(f.Name)
			}
			envPrefix := fmt.Sprintf("[%s]", envKey)
			if strings.HasPrefix(f.Usage, envPrefix) {
				return
			}
			f.Usage = fmt.Sprintf("%s %s", envPrefix, f.Usage)
		})
	}
	for _, envLine := range os.Environ() {
		debug("Find a new line of environment variable, ", envLine)
		envKV := strings.SplitN(envLine, "=", 2)
		var key, value string
		key = envKV[0]
		if len(key) < ef.minLength {
			continue
		}
		if len(envKV) > 1 {
			value = envKV[1]
		} else {
			value = ""
		}
		var flagKey string
		if userFlag, ok := ef.envFlagDict[key]; ok {
			flagKey = userFlag
		} else {
			flagKey = envToFlag(key)
		}
		debug("ENV ", key, " is converted to ", flagKey)
		f := ef.flagSet.Lookup(flagKey)
		if f == nil {
			debug(flagKey, " is not defined in flag, skip!")
			continue
		}
		if ef.showEnvValInUsage {
			f.DefValue = value
		}
		debug("Set  [", flagKey, ",", value, "] to flag")
		if err := ef.flagSet.Set(flagKey, value); err != nil {
			return fmt.Errorf("error when set [%s,%s] into flag\n", flagKey, value)
		}
	}
	return nil
}
func ProcessFlagWithEnv() error {
	return std.ProcessFlagWithEnv()
}
func (ef EnvFlag) Parse(arguments []string) error {
	if err := ef.ProcessFlagWithEnv(); err != nil {
		return err
	}
	return ef.flagSet.Parse(arguments)
}
func Parse() error {
	return std.Parse(os.Args[1:])
}
func (ef *EnvFlag) SetMinLength(v int) {
	ef.minLength = v
}
func SetMinLength(v int) {
	std.SetMinLength(v)
}
func (ef *EnvFlag) SetEnvFlagDict(v map[string]string) {
	ef.envFlagDict = v
}
func SetEnvFlagDict(v map[string]string) {
	std.SetEnvFlagDict(v)
}
func (ef *EnvFlag) SetShowEnvKeyInUsage(v bool) {
	ef.showEnvKeyInUsage = v
}
func SetShowEnvKeyInUsage(v bool) {
	std.showEnvKeyInUsage = v
}
func (ef *EnvFlag) SetShowEnvValInUsage(v bool) {
	ef.showEnvValInUsage = v
}
func SetShowEnvValInUsage(v bool) {
	std.showEnvValInUsage = v
}
var std = NewEnvFlag(flag.CommandLine, 3, map[string]string{}, true, true)
func NewEnvFlag(
	flagSet *flag.FlagSet,
	minLength int,
	envFlagDict map[string]string,
	showEnvKeyInUsage bool,
	showEnvValInUsage bool) *EnvFlag {
	return &EnvFlag{
		flagSet:           flagSet,
		minLength:         minLength,
		envFlagDict:       envFlagDict,
		showEnvKeyInUsage: showEnvKeyInUsage,
		showEnvValInUsage: showEnvValInUsage,
	}
}
func DebugEnabled() bool {
	return debugEnabled
}
func SetDebugEnabled(enabled bool) {
	debugEnabled = enabled
}