// 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"
	"path/filepath"
	"runtime"
	"unicode"
	"unicode/utf8"
)

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

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)
}

func goBin() string {
	return filepath.Join(runtime.GOROOT(), "bin", "go")
}

func determineGoVersion() error {
	goVersionOut, err := exec.Command(goBin(), "version").CombinedOutput()
	if err != nil {
		return fmt.Errorf("'go version' failed: %v, %s", err, goVersionOut)
	}
	var minor int
	if _, err := fmt.Sscanf(string(goVersionOut), "go version go1.%d", &minor); err != nil {
		// Ignore unknown versions; it's probably a devel version.
		return nil
	}
	if minor < 10 {
		return errors.New("Go 1.10 or newer is required")
	}
	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.

// Code generated by 'gomobile help documentation doc.go'. DO NOT EDIT.
`

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,
	cmdClean,
	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.10 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.
`))
