// Copyright 2012 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.

package main

import (
	"flag"
	"fmt"
	"os"
	"strconv"
)

// cmdtab records the available commands.
var cmdtab = []struct {
	name string
	f    func()
}{
	{"banner", cmdbanner},
	{"bootstrap", cmdbootstrap},
	{"clean", cmdclean},
	{"env", cmdenv},
	{"install", cmdinstall},
	{"version", cmdversion},
}

// The OS-specific main calls into the portable code here.
func xmain() {
	if len(os.Args) < 2 {
		usage()
	}
	cmd := os.Args[1]
	os.Args = os.Args[1:] // for flag parsing during cmd
	for _, ct := range cmdtab {
		if ct.name == cmd {
			flag.Usage = func() {
				fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd)
				flag.PrintDefaults()
				os.Exit(2)
			}
			ct.f()
			return
		}
	}

	xprintf("unknown command %s\n", cmd)
	usage()
}

func xflagparse(maxargs int) {
	flag.Var((*count)(&vflag), "v", "verbosity")
	flag.Parse()
	if maxargs >= 0 && flag.NArg() > maxargs {
		flag.Usage()
	}
}

// count is a flag.Value that is like a flag.Bool and a flag.Int.
// If used as -name, it increments the count, but -name=x sets the count.
// Used for verbose flag -v.
type count int

func (c *count) String() string {
	return fmt.Sprint(int(*c))
}

func (c *count) Set(s string) error {
	switch s {
	case "true":
		*c++
	case "false":
		*c = 0
	default:
		n, err := strconv.Atoi(s)
		if err != nil {
			return fmt.Errorf("invalid count %q", s)
		}
		*c = count(n)
	}
	return nil
}

func (c *count) IsBoolFlag() bool {
	return true
}
