// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
	The flag package implements command-line flag parsing.

	Usage:

	1) Define flags using flag.String(), Bool(), Int(), etc. Example:
		import flag "flag"
		var ip *int = flag.Int("flagname", 1234, "help message for flagname")
	If you like, you can bind the flag to a variable using the Var() functions.
		var flagvar int
		func init() {
			flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
		}

	2) After all flags are defined, call
		flag.Parse()
	to parse the command line into the defined flags.

	3) Flags may then be used directly. If you're using the flags themselves,
	they are all pointers; if you bind to variables, they're values.
		print("ip has value ", *ip, "\n");
		print("flagvar has value ", flagvar, "\n");

	4) After parsing, flag.Arg(i) is the i'th argument after the flags.
	Args are indexed from 0 up to flag.NArg().

	Command line flag syntax:
		-flag
		-flag=x
		-flag x
	One or two minus signs may be used; they are equivalent.

	Flag parsing stops just before the first non-flag argument
	("-" is a non-flag argument) or after the terminator "--".

	Integer flags accept 1234, 0664, 0x1234 and may be negative.
	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
 */
package flag

import (
	"fmt";
	"os";
	"strconv"
)

// BUG: atob belongs elsewhere
func atob(str string) (value bool, ok bool) {
	switch str {
		case "1", "t", "T", "true", "TRUE", "True":
			return true, true;
		case "0", "f", "F", "false", "FALSE", "False":
			return false, true
	}
	return false, false
}

type (
	boolValue struct;
	intValue struct;
	int64Value struct;
	uintValue struct;
	uint64Value struct;
	stringValue struct;
)

// -- Bool Value
type boolValue struct {
	p *bool;
}

func newBoolValue(val bool, p *bool) *boolValue {
	*p = val;
	return &boolValue{p}
}

func (b *boolValue) set(s string) bool {
	v, ok  := atob(s);
	*b.p = v;
	return ok
}

func (b *boolValue) String() string {
	return fmt.Sprintf("%v", *b.p)
}

// -- Int Value
type intValue struct {
	p	*int;
}

func newIntValue(val int, p *int) *intValue {
	*p = val;
	return &intValue{p}
}

func (i *intValue) set(s string) bool {
	v, err  := strconv.Atoi(s);
	*i.p = int(v);
	return err == nil
}

func (i *intValue) String() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Int64 Value
type int64Value struct {
	p	*int64;
}

func newInt64Value(val int64, p *int64) *int64Value {
	*p = val;
	return &int64Value{p}
}

func (i *int64Value) set(s string) bool {
	v, err  := strconv.Atoi64(s);
	*i.p = v;
	return err == nil;
}

func (i *int64Value) String() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- Uint Value
type uintValue struct {
	p	*uint;
}

func newUintValue(val uint, p *uint) *uintValue {
	*p = val;
	return &uintValue{p}
}

func (i *uintValue) set(s string) bool {
	v, err  := strconv.Atoui(s);
	*i.p = uint(v);
	return err == nil;
}

func (i *uintValue) String() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- uint64 Value
type uint64Value struct {
	p	*uint64;
}

func newUint64Value(val uint64, p *uint64) *uint64Value {
	*p = val;
	return &uint64Value{p}
}

func (i *uint64Value) set(s string) bool {
	v, err := strconv.Atoui64(s);
	*i.p = uint64(v);
	return err == nil;
}

func (i *uint64Value) String() string {
	return fmt.Sprintf("%v", *i.p)
}

// -- string Value
type stringValue struct {
	p	*string;
}

func newStringValue(val string, p *string) *stringValue {
	*p = val;
	return &stringValue{p}
}

func (s *stringValue) set(val string) bool {
	*s.p = val;
	return true;
}

func (s *stringValue) String() string {
	return fmt.Sprintf("%s", *s.p)
}

// FlagValue is the interface to the dynamic value stored in a flag.
// (The default value is represented as a string.)
type FlagValue interface {
	String() string;
	set(string) bool;
}

// A Flag represents the state of a flag.
type Flag struct {
	Name	string;	// name as it appears on command line
	Usage	string;	// help message
	Value	FlagValue;	// value as set
	DefValue	string;	// default value (as text); for usage message
}

type allFlags struct {
	actual map[string] *Flag;
	formal map[string] *Flag;
	first_arg	int;	// 0 is the program name, 1 is first arg
}

var flags *allFlags = &allFlags{make(map[string] *Flag), make(map[string] *Flag), 1}

// VisitAll visits the flags, calling fn for each. It visits all flags, even those not set.
func VisitAll(fn func(*Flag)) {
	for k, f := range flags.formal {
		fn(f)
	}
}

// Visit visits the flags, calling fn for each. It visits only those flags that have been set.
func Visit(fn func(*Flag)) {
	for k, f := range flags.actual {
		fn(f)
	}
}

// Lookup returns the Flag structure of the named flag, returning nil if none exists.
func Lookup(name string) *Flag {
	f, ok := flags.formal[name];
	if !ok {
		return nil
	}
	return f
}

// Set sets the value of the named flag.  It returns true if the set succeeded; false if
// there is no such flag defined.
func Set(name, value string) bool {
	f, ok := flags.formal[name];
	if !ok {
		return false
	}
	ok = f.Value.set(value);
	if !ok {
		return false
	}
	flags.actual[name] = f;
	return true;
}

// PrintDefaults prints to standard error the default values of all defined flags.
func PrintDefaults() {
	VisitAll(func(f *Flag) {
		format := "  -%s=%s: %s\n";
		if s, ok := f.Value.(*stringValue); ok {
			// put quotes on the value
			format = "  -%s=%q: %s\n";
		}
		fmt.Fprintf(os.Stderr, format, f.Name, f.DefValue, f.Usage);
	})
}

// Usage prints to standard error a default usage message documenting all defined flags and
// then calls os.Exit(1).
func Usage() {
	if len(os.Args) > 0 {
		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]);
	} else {
		fmt.Fprintln(os.Stderr, "Usage:");
	}
	PrintDefaults();
	os.Exit(1);
}

func NFlag() int {
	return len(flags.actual)
}

// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
// after flags have been processed.
func Arg(i int) string {
	i += flags.first_arg;
	if i < 0 || i >= len(os.Args) {
		return "";
	}
	return os.Args[i]
}

// NArg is the number of arguments remaining after flags have been processed.
func NArg() int {
	return len(os.Args) - flags.first_arg
}

// Args returns the non-flag command-line arguments.
func Args() []string {
	return os.Args[flags.first_arg:len(os.Args)];
}

func add(name string, value FlagValue, usage string) {
	// Remember the default value as a string; it won't change.
	f := &Flag{name, usage, value, value.String()};
	dummy, alreadythere := flags.formal[name];
	if alreadythere {
		print("flag redefined: ", name, "\n");
		panic("flag redefinition");	// Happens only if flags are declared with identical names
	}
	flags.formal[name] = f;
}

// BoolVar defines a bool flag with specified name, default value, and usage string.
// The argument p points to a bool variable in which to store the value of the flag.
func BoolVar(p *bool, name string, value bool, usage string) {
	add(name, newBoolValue(value, p), usage);
}

// Bool defines a bool flag with specified name, default value, and usage string.
// The return value is the address of a bool variable that stores the value of the flag.
func Bool(name string, value bool, usage string) *bool {
	p := new(bool);
	BoolVar(p, name, value, usage);
	return p;
}

// IntVar defines an int flag with specified name, default value, and usage string.
// The argument p points to an int variable in which to store the value of the flag.
func IntVar(p *int, name string, value int, usage string) {
	add(name, newIntValue(value, p), usage);
}

// Int defines an int flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
func Int(name string, value int, usage string) *int {
	p := new(int);
	IntVar(p, name, value, usage);
	return p;
}

// Int64Var defines an int64 flag with specified name, default value, and usage string.
// The argument p points to an int64 variable in which to store the value of the flag.
func Int64Var(p *int64, name string, value int64, usage string) {
	add(name, newInt64Value(value, p), usage);
}

// Int64 defines an int64 flag with specified name, default value, and usage string.
// The return value is the address of an int64 variable that stores the value of the flag.
func Int64(name string, value int64, usage string) *int64 {
	p := new(int64);
	Int64Var(p, name, value, usage);
	return p;
}

// UintVar defines a uint flag with specified name, default value, and usage string.
// The argument p points to a uint variable in which to store the value of the flag.
func UintVar(p *uint, name string, value uint, usage string) {
	add(name, newUintValue(value, p), usage);
}

// Uint defines a uint flag with specified name, default value, and usage string.
// The return value is the address of a uint variable that stores the value of the flag.
func Uint(name string, value uint, usage string) *uint {
	p := new(uint);
	UintVar(p, name, value, usage);
	return p;
}

// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
// The argument p points to a uint64 variable in which to store the value of the flag.
func Uint64Var(p *uint64, name string, value uint64, usage string) {
	add(name, newUint64Value(value, p), usage);
}

// Uint64 defines a uint64 flag with specified name, default value, and usage string.
// The return value is the address of a uint64 variable that stores the value of the flag.
func Uint64(name string, value uint64, usage string) *uint64 {
	p := new(uint64);
	Uint64Var(p, name, value, usage);
	return p;
}

// StringVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a string variable in which to store the value of the flag.
func StringVar(p *string, name, value string, usage string) {
	add(name, newStringValue(value, p), usage);
}

// String defines a string flag with specified name, default value, and usage string.
// The return value is the address of a string variable that stores the value of the flag.
func String(name, value string, usage string) *string {
	p := new(string);
	StringVar(p, name, value, usage);
	return p;
}

func (f *allFlags) parseOne(index int) (ok bool, next int)
{
	s := os.Args[index];
	f.first_arg = index;  // until proven otherwise
	if len(s) == 0 {
		return false, -1
	}
	if s[0] != '-' {
		return false, -1
	}
	num_minuses := 1;
	if len(s) == 1 {
		return false, index
	}
	if s[1] == '-' {
		num_minuses++;
		if len(s) == 2 {	// "--" terminates the flags
			return false, index + 1
		}
	}
	name := s[num_minuses : len(s)];
	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
		print("bad flag syntax: ", s, "\n");
		Usage();
	}

	// it's a flag. does it have an argument?
	has_value := false;
	value := "";
	for i := 1; i < len(name); i++ {  // equals cannot be first
		if name[i] == '=' {
			value = name[i+1 : len(name)];
			has_value = true;
			name = name[0 : i];
			break;
		}
	}
	flag, alreadythere := flags.actual[name];
	if alreadythere {
		print("flag specified twice: -", name, "\n");
		Usage();
	}
	m := flags.formal;
	flag, alreadythere = m[name]; // BUG
	if !alreadythere {
		print("flag provided but not defined: -", name, "\n");
		Usage();
	}
	if f, ok := flag.Value.(*boolValue); ok {	// special case: doesn't need an arg
		if has_value {
			if !f.set(value) {
				print("invalid boolean value ", value, " for flag: -", name, "\n");
				Usage();
			}
		} else {
			f.set("true")
		}
	} else {
		// It must have a value, which might be the next argument.
		if !has_value && index < len(os.Args)-1 {
			// value is the next arg
			has_value = true;
			index++;
			value = os.Args[index];
		}
		if !has_value {
			print("flag needs an argument: -", name, "\n");
			Usage();
		}
		ok = flag.Value.set(value);
		if !ok {
			print("invalid value ", value, " for flag: -", name, "\n");
				Usage();
		}
	}
	flags.actual[name] = flag;
	return true, index + 1
}

// Parse parses the command-line flags.  Must be called after all flags are defined
// and before any are accessed by the program.
func Parse() {
	for i := 1; i < len(os.Args); {
		ok, next := flags.parseOne(i);
		if next > 0 {
			flags.first_arg = next;
			i = next;
		}
		if !ok {
			break
		}
	}
}
