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

// TODO(adg): recognize non-master remote branches
// TODO(adg): accept -a flag on 'commit' (like git commit -a)
// TODO(adg): check style of commit message
// TOOD(adg): print gerrit votes on 'pending'
// TODO(adg): add gofmt commit hook
// TODO(adg): print changed files on review sync
// TODO(adg): translate email addresses without @ by looking up somewhere

// Command review provides a simple command-line user interface for
// working with git repositories and the Gerrit code review system.
// See "review help" for details.
package main // import "golang.org/x/review"

import (
	"bytes"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

var (
	flags   = flag.NewFlagSet("", flag.ExitOnError)
	verbose = flags.Bool("v", false, "verbose output")
	noRun   = flags.Bool("n", false, "print but do not run commands")
)

const globalFlags = "[-n] [-v]"

const usage = `Usage: %s <command> ` + globalFlags + `
Type "%s help" for more information.
`

func init() {
	flags.Usage = func() {
		fmt.Fprintf(os.Stderr, usage, os.Args[0], os.Args[0])
	}
}

const help = `Usage: %s <command> ` + globalFlags + `

The review command is a wrapper for the git command that provides a simple
interface to the "single-commit feature branch" development model.

Available comands:

	change [name]
		Create a change commit, or amend an existing change commit,
		with the staged changes. If a branch name is provided, check
		out that branch (creating it if it does not exist).
		(Does not amend the existing commit when switching branches.)

	pending [-r]
		Show local branches and their head commits.
		If -r is specified, show additional information from Gerrit.

	mail [-f] [-r reviewer,...] [-cc mail,...]
		Upload change commit to the code review server and send mail
		requesting a code review.
		If -f is specified, upload even if there are staged changes.

	mail -diff
		Show the changes but do not send mail or upload.

	sync
		Fetch changes from the remote repository and merge them into
		the current branch, rebasing the change commit on top of them.

	revert files...
		Revert the specified files to their state before the change
		commit. (Be careful! This will discard your changes!)

	gofmt
		TBD

`

func main() {
	installHook()

	if len(os.Args) < 2 {
		flags.Usage()
		os.Exit(2)
	}
	command, args := os.Args[1], os.Args[2:]

	switch command {
	case "help":
		fmt.Fprintf(os.Stdout, help, os.Args[0])
	case "change", "c":
		change(args)
	case "pending", "p":
		pending(args)
	case "mail", "m":
		mail(args)
	case "sync", "s":
		doSync(args)
	case "revert":
		dief("revert not implemented")
	case "gofmt":
		dief("gofmt not implemented")
	default:
		flags.Usage()
	}
}

func expectZeroArgs(args []string, command string) {
	flags.Parse(args)
	if len(flags.Args()) > 0 {
		fmt.Fprintf(os.Stderr, "Usage: %s %s %s\n", os.Args[0], command, globalFlags)
		os.Exit(2)
	}
}

func run(command string, args ...string) {
	if err := runErr(command, args...); err != nil {
		if !*verbose {
			// If we're not in verbose mode, print the command
			// before dying to give context to the failure.
			fmt.Fprintln(os.Stderr, commandString(command, args))
		}
		dief("%v", err)
	}
}

func runErr(command string, args ...string) error {
	if *verbose || *noRun {
		fmt.Fprintln(os.Stderr, commandString(command, args))
	}
	if *noRun {
		return nil
	}
	cmd := exec.Command(command, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

// getOutput runs the specified command and returns its combined standard
// output and standard error outputs.
// NOTE: It should only be used to run commands that return information,
// **not** commands that make any actual changes.
func getOutput(command string, args ...string) string {
	if *verbose {
		fmt.Fprintln(os.Stderr, commandString(command, args))
	}
	b, err := exec.Command(command, args...).CombinedOutput()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n%s\n", commandString(command, args), b)
		dief("%v", err)
	}
	return string(bytes.TrimSpace(b))
}

// getLines is like getOutput but it returns non-empty output lines.
// NOTE: It should only be used to run commands that return information,
// **not** commands that make any actual changes.
func getLines(command string, args ...string) []string {
	var s []string
	for _, l := range strings.Split(getOutput(command, args...), "\n") {
		s = append(s, strings.TrimSpace(l))
	}
	return s
}

func commandString(command string, args []string) string {
	return strings.Join(append([]string{command}, args...), " ")
}

func dief(format string, args ...interface{}) {
	printf(format, args...)
	os.Exit(1)
}

func verbosef(format string, args ...interface{}) {
	if *verbose {
		printf(format, args...)
	}
}

func printf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "review: "+format+"\n", args...)
}
