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

package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

var commitMsg string
var changeAuto bool
var changeQuick bool

func cmdChange(args []string) {
	// NOTE: New flags should be added to the usage message below as well as doc.go.
	flags.StringVar(&commitMsg, "m", "", "specify a commit message")
	flags.BoolVar(&changeAuto, "a", false, "add changes to any tracked files")
	flags.BoolVar(&changeQuick, "q", false, "do not edit pending commit msg")
	flags.Parse(args)
	if len(flags.Args()) > 1 {
		fmt.Fprintf(stderr(), "Usage: %s change %s [-a] [-m msg] [-q] [branch]\n", progName, globalFlags)
		exit(2)
	}

	// Checkout or create branch, if specified.
	target := flags.Arg(0)
	if target != "" {
		checkoutOrCreate(target)
		b := CurrentBranch()
		if HasStagedChanges() && b.IsLocalOnly() && !b.HasPendingCommit() {
			commitChanges(false)
		}
		b.check()
		return
	}

	// Create or amend change commit.
	b := CurrentBranch()
	if !b.IsLocalOnly() {
		dief("can't commit to %s branch (use '%s change branchname').", b.Name, progName)
	}

	amend := b.HasPendingCommit()
	if amend {
		// Dies if there is not exactly one commit.
		b.DefaultCommit("amend change", "")
	}
	commitChanges(amend)
	b.loadedPending = false // force reload after commitChanges
	b.check()
}

func (b *Branch) check() {
	staged, unstaged, _ := LocalChanges()
	if len(staged) == 0 && len(unstaged) == 0 {
		// No staged changes, no unstaged changes.
		// If the branch is behind upstream, now is a good time to point that out.
		// This applies to both local work branches and tracking branches.
		b.loadPending()
		if n := b.CommitsBehind(); n > 0 {
			printf("warning: %d commit%s behind %s; run 'git codereview sync' to update.", n, suffix(n, "s"), b.OriginBranch())
		}
	}

	// TODO(rsc): Test
	if text := b.errors(); text != "" {
		printf("error: %s\n", text)
	}
}

var testCommitMsg string

func commitChanges(amend bool) {
	// git commit will run the gofmt hook.
	// Run it now to give a better error (won't show a git commit command failing).
	hookGofmt()

	if HasUnstagedChanges() && !HasStagedChanges() && !changeAuto {
		printf("warning: unstaged changes and no staged changes; use 'git add' or 'git change -a'")
	}
	commit := func(amend bool) {
		args := []string{"commit", "-q", "--allow-empty"}
		if amend {
			args = append(args, "--amend")
			if changeQuick {
				args = append(args, "--no-edit")
			}
		}
		if commitMsg != "" {
			args = append(args, "-m", commitMsg)
		} else if testCommitMsg != "" {
			args = append(args, "-m", testCommitMsg)
		}
		if changeAuto {
			args = append(args, "-a")
		}
		run("git", args...)
	}
	commit(amend)
	for !commitMessageOK() {
		fmt.Print("re-edit commit message (y/n)? ")
		if !scanYes() {
			break
		}
		commit(true)
	}
	printf("change updated.")
}

func checkoutOrCreate(target string) {
	// If it's a valid Gerrit number, checkout the CL.
	cl, ps, isCL := parseCL(target)
	if isCL {
		if !haveGerrit() {
			dief("cannot change to a CL without gerrit")
		}
		if HasStagedChanges() || HasUnstagedChanges() {
			dief("cannot change to a CL with uncommitted work")
		}
		checkoutCL(cl, ps)
		return
	}

	if strings.ToUpper(target) == "HEAD" {
		// Git gets very upset and confused if you 'git change head'
		// on systems with case-insensitive file names: the branch
		// head conflicts with the usual HEAD.
		dief("invalid branch name %q: ref name HEAD is reserved for git.", target)
	}

	// If local branch exists, check it out.
	for _, b := range LocalBranches() {
		if b.Name == target {
			run("git", "checkout", "-q", target)
			printf("changed to branch %v.", target)
			return
		}
	}

	// If origin branch exists, create local branch tracking it.
	for _, name := range OriginBranches() {
		if name == "origin/"+target {
			run("git", "checkout", "-q", "-t", "-b", target, name)
			printf("created branch %v tracking %s.", target, name)
			return
		}
	}

	// Otherwise, this is a request to create a local work branch.
	// Check for reserved names. We take everything with a dot.
	if strings.Contains(target, ".") {
		dief("invalid branch name %v: branch names with dots are reserved for git-codereview.", target)
	}

	// If the current branch has a pending commit, building
	// on top of it will not help. Don't allow that.
	// Otherwise, inherit HEAD and upstream from the current branch.
	b := CurrentBranch()
	if b.HasPendingCommit() {
		if !b.IsLocalOnly() {
			dief("bad repo state: branch %s is ahead of origin/%s", b.Name, b.Name)
		}
		dief("cannot branch from work branch; change back to %v first.", strings.TrimPrefix(b.OriginBranch(), "origin/"))
	}

	origin := b.OriginBranch()

	// NOTE: This is different from git checkout -q -t -b branch. It does not move HEAD.
	run("git", "checkout", "-q", "-b", target)
	run("git", "branch", "-q", "--set-upstream-to", origin)
	printf("created branch %v tracking %s.", target, origin)
}

// Checkout the patch set of the given CL. When patch set is empty, use the latest.
func checkoutCL(cl, ps string) {
	if ps == "" {
		change, err := readGerritChange(cl + "?o=CURRENT_REVISION")
		if err != nil {
			dief("cannot change to CL %s: %v", cl, err)
		}
		rev, ok := change.Revisions[change.CurrentRevision]
		if !ok {
			dief("cannot change to CL %s: invalid current revision from gerrit", cl)
		}
		ps = strconv.Itoa(rev.Number)
	}

	var group string
	if len(cl) > 1 {
		group = cl[len(cl)-2:]
	} else {
		group = "0" + cl
	}
	ref := fmt.Sprintf("refs/changes/%s/%s/%s", group, cl, ps)

	err := runErr("git", "fetch", "-q", "origin", ref)
	if err != nil {
		dief("cannot change to CL %s/%s: %v", cl, ps, err)
	}
	err = runErr("git", "checkout", "-q", "FETCH_HEAD")
	if err != nil {
		dief("cannot change to CL %s/%s: %v", cl, ps, err)
	}
	subject, err := trimErr(cmdOutputErr("git", "log", "--format=%s", "-1"))
	if err != nil {
		printf("changed to CL %s/%s.", cl, ps)
		dief("cannot read change subject from git: %v", err)
	}
	printf("changed to CL %s/%s.\n\t%s", cl, ps, subject)
}

var parseCLRE = regexp.MustCompile(`^([0-9]+)(?:/([0-9]+))?$`)

// parseCL validates and splits the CL number and patch set (if present).
func parseCL(arg string) (cl, patchset string, ok bool) {
	m := parseCLRE.FindStringSubmatch(arg)
	if len(m) == 0 {
		return "", "", false
	}
	return m[1], m[2], true
}

var messageRE = regexp.MustCompile(`^(\[[a-zA-Z0-9.-]+\] )?[a-zA-Z0-9-/,. ]+: `)

func commitMessageOK() bool {
	body := cmdOutput("git", "log", "--format=format:%B", "-n", "1")
	ok := true
	if !messageRE.MatchString(body) {
		fmt.Print(commitMessageWarning)
		ok = false
	}
	return ok
}

const commitMessageWarning = `
Your CL description appears not to use the standard form.

The first line of your change description is conventionally a one-line summary
of the change, prefixed by the primary affected package, and is used as the
subject for code review mail; the rest of the description elaborates.

Examples:

	encoding/rot13: new package

	math: add IsInf, IsNaN

	net: fix cname in LookupHost

	unicode: update to Unicode 5.0.2

`

func scanYes() bool {
	var s string
	fmt.Scan(&s)
	return strings.HasPrefix(strings.ToLower(s), "y")
}
