// Copyright 2015 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

//go:generate gomobile help documentation doc.go

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"unicode"
	"unicode/utf8"
)

var (
	gomobileName = "gomobile"
	goVersionOut = []byte(nil)
	goVersion    = go1_5
)

func printUsage(w io.Writer) {
	bufw := bufio.NewWriter(w)
	if err := usageTmpl.Execute(bufw, commands); err != nil {
		panic(err)
	}
	bufw.Flush()
}

func main() {
	gomobileName = os.Args[0]
	flag.Usage = func() {
		printUsage(os.Stderr)
		os.Exit(2)
	}
	flag.Parse()
	log.SetFlags(0)

	args := flag.Args()
	if len(args) < 1 {
		flag.Usage()
	}

	if args[0] == "help" {
		if len(args) == 3 && args[1] == "documentation" {
			helpDocumentation(args[2])
			return
		}
		help(args[1:])
		return
	}

	if err := determineGoVersion(); err != nil {
		fmt.Fprintf(os.Stderr, "%s: %v\n", gomobileName, err)
		os.Exit(1)
	}

	for _, cmd := range commands {
		if cmd.Name == args[0] {
			cmd.flag.Usage = func() {
				cmd.usage()
				os.Exit(1)
			}
			cmd.flag.Parse(args[1:])
			if err := cmd.run(cmd); err != nil {
				msg := err.Error()
				if msg != "" {
					fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
				}
				os.Exit(1)
			}
			return
		}
	}
	fmt.Fprintf(os.Stderr, "%s: unknown subcommand %q\nRun 'gomobile help' for usage.\n", os.Args[0], args[0])
	os.Exit(2)
}

type goToolVersion int

const (
	go1_5 goToolVersion = iota
	go1_6
)

func determineGoVersion() error {
	gobin, err := exec.LookPath("go")
	if err != nil {
		return errors.New("go not found")
	}
	goVersionOut, err = exec.Command(gobin, "version").CombinedOutput()
	if err != nil {
		return fmt.Errorf("'go version' failed: %v, %s", err, goVersionOut)
	}
	switch {
	case bytes.HasPrefix(goVersionOut, []byte("go version go1.4")):
		return errors.New("Go 1.5 or newer is required")
	case bytes.HasPrefix(goVersionOut, []byte("go version go1.5")):
		goVersion = go1_5
	default:
		goVersion = go1_6 // assume developers are working at tip
	}
	return nil
}

func help(args []string) {
	if len(args) == 0 {
		printUsage(os.Stdout)
		return // succeeded at helping
	}
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "usage: %s help command\n\nToo many arguments given.\n", gomobileName)
		os.Exit(2) // failed to help
	}

	arg := args[0]
	for _, cmd := range commands {
		if cmd.Name == arg {
			cmd.usage()
			return // succeeded at helping
		}
	}

	fmt.Fprintf(os.Stderr, "Unknown help topic %#q.  Run '%s help'.\n", arg, gomobileName)
	os.Exit(2)
}

const documentationHeader = `// Copyright 2015 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.

// DO NOT EDIT. GENERATED BY 'gomobile help documentation doc.go'.
`

func helpDocumentation(path string) {
	w := new(bytes.Buffer)
	w.WriteString(documentationHeader)
	w.WriteString("\n/*\n")
	if err := usageTmpl.Execute(w, commands); err != nil {
		log.Fatal(err)
	}

	for _, cmd := range commands {
		r, rlen := utf8.DecodeRuneInString(cmd.Short)
		w.WriteString("\n\n")
		w.WriteRune(unicode.ToUpper(r))
		w.WriteString(cmd.Short[rlen:])
		w.WriteString("\n\nUsage:\n\n\tgomobile " + cmd.Name)
		if cmd.Usage != "" {
			w.WriteRune(' ')
			w.WriteString(cmd.Usage)
		}
		w.WriteRune('\n')
		w.WriteString(cmd.Long)
	}

	w.WriteString("*/\npackage main // import \"golang.org/x/mobile/cmd/gomobile\"\n")

	if err := ioutil.WriteFile(path, w.Bytes(), 0666); err != nil {
		log.Fatal(err)
	}
}

var commands = []*command{
	// TODO(crawshaw): cmdRun
	cmdBind,
	cmdBuild,
	cmdInit,
	cmdInstall,
	cmdVersion,
}

type command struct {
	run   func(*command) error
	flag  flag.FlagSet
	Name  string
	Usage string
	Short string
	Long  string
}

func (cmd *command) usage() {
	fmt.Fprintf(os.Stdout, "usage: %s %s %s\n%s", gomobileName, cmd.Name, cmd.Usage, cmd.Long)
}

var usageTmpl = template.Must(template.New("usage").Parse(
	`Gomobile is a tool for building and running mobile apps written in Go.

To install:

	$ go get golang.org/x/mobile/cmd/gomobile
	$ gomobile init

At least Go 1.5 is required.
For detailed instructions, see https://golang.org/wiki/Mobile.

Usage:

	gomobile command [arguments]

Commands:
{{range .}}
	{{.Name | printf "%-11s"}} {{.Short}}{{end}}

Use 'gomobile help [command]' for more information about that command.
`))
