// 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.HasPendingCommit() {
			commitChanges(false)
		}
		b.check()
		return
	}

	// Create or amend change commit.
	b := CurrentBranch()
	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())
		}
	}
}

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 branchpoint and upstream from the current branch.
	b := CurrentBranch()
	branchpoint := "HEAD"
	if b.HasPendingCommit() {
		fmt.Fprintf(stderr(), "warning: pending changes on %s are not copied to new branch %s\n", b.Name, target)
		branchpoint = b.Branchpoint()
	}

	origin := b.OriginBranch()

	// NOTE: This is different from git checkout -q -t -b origin,
	// because the -t wold use the origin directly, and that may be
	// ahead of the current directory. The goal of this command is
	// to create a new branch for work on the current directory,
	// not to incorporate new commits at the same time (use 'git sync' for that).
	// The ideal is that HEAD doesn't change at all.
	// In the absence of pending commits, that ideal is achieved.
	// But if there are pending commits, it'd be too confusing to have them
	// on two different work branches, so we drop them and use the
	// branchpoint they started from (after warning above), moving HEAD
	// as little as possible.
	run("git", "checkout", "-q", "-b", target, branchpoint)
	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")
}
