// 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 (
	"bytes"
	"fmt"
	"os"
	"strings"
	"time"
)

// TODO(rsc): Add -tbr, along with standard exceptions (doc/go1.5.txt)

func cmdSubmit(args []string) {
	var interactive bool
	flags.BoolVar(&interactive, "i", false, "interactively select commits to submit")
	flags.Usage = func() {
		fmt.Fprintf(stderr(), "Usage: %s submit %s [-i | commit...]\n", os.Args[0], globalFlags)
	}
	flags.Parse(args)
	if interactive && flags.NArg() > 0 {
		flags.Usage()
		os.Exit(2)
	}

	b := CurrentBranch()
	var cs []*Commit
	if interactive {
		hashes := submitHashes(b)
		if len(hashes) == 0 {
			printf("nothing to submit")
			return
		}
		for _, hash := range hashes {
			cs = append(cs, b.CommitByRev("submit", hash))
		}
	} else if args := flags.Args(); len(args) >= 1 {
		for _, arg := range args {
			cs = append(cs, b.CommitByRev("submit", arg))
		}
	} else {
		cs = append(cs, b.DefaultCommit("submit", "must specify commit on command line or use submit -i"))
	}

	// No staged changes.
	// Also, no unstaged changes, at least for now.
	// This makes sure the sync at the end will work well.
	// We can relax this later if there is a good reason.
	checkStaged("submit")
	checkUnstaged("submit")

	// Submit the changes.
	var g *GerritChange
	for _, c := range cs {
		printf("submitting %s %s", c.ShortHash, c.Subject)
		g = submit(b, c)
	}

	// Sync client to revision that Gerrit committed, but only if we can do it cleanly.
	// Otherwise require user to run 'git sync' themselves (if they care).
	run("git", "fetch", "-q")
	if len(cs) == 1 && len(b.Pending()) == 1 {
		if err := runErr("git", "checkout", "-q", "-B", b.Name, g.CurrentRevision, "--"); err != nil {
			dief("submit succeeded, but cannot sync local branch\n"+
				"\trun 'git sync' to sync, or\n"+
				"\trun 'git branch -D %s; git change master; git sync' to discard local branch", b.Name)
		}
	} else {
		printf("submit succeeded; run 'git sync' to sync")
	}

	// Done! Change is submitted, branch is up to date, ready for new work.
}

// submit submits a single commit c on branch b and returns the
// GerritChange for the submitted change. It dies if the submit fails.
func submit(b *Branch, c *Commit) *GerritChange {
	if strings.Contains(strings.ToLower(c.Message), "do not submit") {
		dief("%s: CL says DO NOT SUBMIT", c.ShortHash)
	}

	// Fetch Gerrit information about this change.
	g, err := b.GerritChange(c, "LABELS", "CURRENT_REVISION")
	if err != nil {
		dief("%v", err)
	}

	// Pre-check that this change appears submittable.
	// The final submit will check this too, but it is better to fail now.
	if err = submitCheck(g); err != nil {
		dief("cannot submit: %v", err)
	}

	// Upload most recent revision if not already on server.

	if c.Hash != g.CurrentRevision {
		run("git", "push", "-q", "origin", b.PushSpec(c))

		// Refetch change information, especially mergeable.
		g, err = b.GerritChange(c, "LABELS", "CURRENT_REVISION")
		if err != nil {
			dief("%v", err)
		}
	}

	// Don't bother if the server can't merge the changes.
	if !g.Mergeable {
		// Server cannot merge; explicit sync is needed.
		dief("cannot submit: conflicting changes submitted, run 'git sync'")
	}

	if *noRun {
		printf("stopped before submit")
		return g
	}

	// Otherwise, try the submit. Sends back updated GerritChange,
	// but we need extended information and the reply is in the
	// "SUBMITTED" state anyway, so ignore the GerritChange
	// in the response and fetch a new one below.
	if err := gerritAPI("/a/changes/"+fullChangeID(b, c)+"/submit", []byte(`{"wait_for_merge": true}`), nil); err != nil {
		dief("cannot submit: %v", err)
	}

	// It is common to get back "SUBMITTED" for a split second after the
	// request is made. That indicates that the change has been queued for submit,
	// but the first merge (the one wait_for_merge waited for)
	// failed, possibly due to a spurious condition. We see this often, and the
	// status usually changes to MERGED shortly thereafter.
	// Wait a little while to see if we can get to a different state.
	const steps = 6
	const max = 2 * time.Second
	for i := 0; i < steps; i++ {
		time.Sleep(max * (1 << uint(i+1)) / (1 << steps))
		g, err = b.GerritChange(c, "LABELS", "CURRENT_REVISION")
		if err != nil {
			dief("waiting for merge: %v", err)
		}
		if g.Status != "SUBMITTED" {
			break
		}
	}

	switch g.Status {
	default:
		dief("submit error: unexpected post-submit Gerrit change status %q", g.Status)

	case "MERGED":
		// good

	case "SUBMITTED":
		// see above
		dief("cannot submit: timed out waiting for change to be submitted by Gerrit")
	}

	return g
}

// submitCheck checks that g should be submittable. This is
// necessarily a best-effort check.
//
// g must have the "LABELS" option.
func submitCheck(g *GerritChange) error {
	// Check Gerrit change status.
	switch g.Status {
	default:
		return fmt.Errorf("unexpected Gerrit change status %q", g.Status)

	case "NEW", "SUBMITTED":
		// Not yet "MERGED", so try the submit.
		// "SUBMITTED" is a weird state. It means that Submit has been clicked once,
		// but it hasn't happened yet, usually because of a merge failure.
		// The user may have done git sync and may now have a mergable
		// copy waiting to be uploaded, so continue on as if it were "NEW".

	case "MERGED":
		// Can happen if moving between different clients.
		return fmt.Errorf("change already submitted, run 'git sync'")

	case "ABANDONED":
		return fmt.Errorf("change abandoned")
	}

	// Check for label approvals (like CodeReview+2).
	for _, name := range g.LabelNames() {
		label := g.Labels[name]
		if label.Optional {
			continue
		}
		if label.Rejected != nil {
			return fmt.Errorf("change has %s rejection", name)
		}
		if label.Approved == nil {
			return fmt.Errorf("change missing %s approval", name)
		}
	}

	return nil
}

// submitHashes interactively prompts for commits to submit.
func submitHashes(b *Branch) []string {
	// Get pending commits on b.
	pending := b.Pending()
	for _, c := range pending {
		// Note that DETAILED_LABELS does not imply LABELS.
		c.g, c.gerr = b.GerritChange(c, "CURRENT_REVISION", "LABELS", "DETAILED_LABELS")
		if c.g == nil {
			c.g = new(GerritChange)
		}
	}

	// Construct submit script.
	var script bytes.Buffer
	for i := len(pending) - 1; i >= 0; i-- {
		c := pending[i]

		if c.g.ID == "" {
			fmt.Fprintf(&script, "# change not on Gerrit:\n#")
		} else if err := submitCheck(c.g); err != nil {
			fmt.Fprintf(&script, "# %v:\n#", err)
		}

		formatCommit(&script, c, true)
	}

	fmt.Fprintf(&script, `
# The above commits will be submitted in order from top to bottom
# when you exit the editor.
#
# These lines can be re-ordered, removed, and commented out.
#
# If you remove all lines, the submit will be aborted.
`)

	// Edit the script.
	final := editor(script.String())

	// Parse the final script.
	var hashes []string
	for _, line := range lines(final) {
		line := strings.TrimSpace(line)
		if len(line) == 0 || line[0] == '#' {
			continue
		}
		if i := strings.Index(line, " "); i >= 0 {
			line = line[:i]
		}
		hashes = append(hashes, line)
	}

	return hashes
}
