// 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"
	"io"
	"net/http"
	"sort"
	"strings"
	"time"
)

var (
	pendingLocal       bool // -l flag, use only local operations (no network)
	pendingCurrentOnly bool // -c flag, show only current branch
	pendingShort       bool // -s flag, short display
)

// A pendingBranch collects information about a single pending branch.
// We overlap the reading of this information for each branch.
type pendingBranch struct {
	*Branch            // standard Branch functionality
	current   bool     // is this the current branch?
	staged    []string // files in staging area, only if current==true
	unstaged  []string // files unstaged in local directory, only if current==true
	untracked []string // files untracked in local directory, only if current==true
}

// load populates b with information about the branch.
func (b *pendingBranch) load() {
	b.loadPending()
	if !b.current && b.commitsAhead == 0 {
		// Won't be displayed, don't bother looking any closer.
		return
	}
	b.OriginBranch() // cache result
	if b.current {
		b.staged, b.unstaged, b.untracked = LocalChanges()
	}
	var changeIDs []string
	var commits []*Commit
	for _, c := range b.Pending() {
		c.committed = ListFiles(c)
		if c.ChangeID == "" {
			c.gerr = fmt.Errorf("missing Change-Id in commit message")
		} else {
			changeIDs = append(changeIDs, fullChangeID(b.Branch, c))
			commits = append(commits, c)
		}
	}
	if !pendingLocal {
		gs, err := b.GerritChanges(changeIDs, "DETAILED_LABELS", "CURRENT_REVISION", "MESSAGES", "DETAILED_ACCOUNTS")
		if len(gs) != len(commits) && err == nil {
			err = fmt.Errorf("invalid response from Gerrit server - %d queries but %d results", len(changeIDs), len(gs))
		}
		if err != nil {
			for _, c := range commits {
				if c.gerr != nil {
					c.gerr = err
				}
			}
		} else {
			for i, c := range commits {
				if len(gs[i]) == 1 {
					c.g = gs[i][0]
				}
			}
		}
	}
	for _, c := range b.Pending() {
		if c.g == nil {
			c.g = new(GerritChange) // easier for formatting code
		}
	}
}

func cmdPending(args []string) {
	// NOTE: New flags should be added to the usage message below as well as doc.go.
	flags.BoolVar(&pendingCurrentOnly, "c", false, "show only current branch")
	flags.BoolVar(&pendingLocal, "l", false, "use only local information - no network operations")
	flags.BoolVar(&pendingShort, "s", false, "show short listing")
	flags.Parse(args)
	if len(flags.Args()) > 0 {
		fmt.Fprintf(stderr(), "Usage: %s pending %s [-c] [-l] [-s]\n", progName, globalFlags)
		exit(2)
	}

	// Fetch info about remote changes, so that we can say which branches need sync.
	doneFetch := make(chan bool, 1)
	if pendingLocal {
		doneFetch <- true
	} else {
		http.DefaultClient.Timeout = 60 * time.Second
		go func() {
			run("git", "fetch", "-q")
			doneFetch <- true
		}()
	}

	// Build list of pendingBranch structs to be filled in.
	// The current branch is always first.
	var branches []*pendingBranch
	branches = []*pendingBranch{{Branch: CurrentBranch(), current: true}}
	if !pendingCurrentOnly {
		current := CurrentBranch().Name
		for _, b := range LocalBranches() {
			if b.Name != current {
				branches = append(branches, &pendingBranch{Branch: b})
			}
		}
	}

	// The various data gathering is a little slow,
	// especially run in serial with a lot of branches.
	// Overlap inspection of multiple branches.
	// Each branch is only accessed by a single worker.

	// Build work queue.
	work := make(chan *pendingBranch, len(branches))
	done := make(chan bool, len(branches))
	for _, b := range branches {
		work <- b
	}
	close(work)

	// Kick off goroutines to do work.
	n := len(branches)
	if n > 10 {
		n = 10
	}
	for i := 0; i < n; i++ {
		go func() {
			for b := range work {
				// This b.load may be using a stale origin/master ref, which is OK.
				b.load()
				done <- true
			}
		}()
	}

	// Wait for goroutines to finish.
	// Note: Counting work items, not goroutines (there may be fewer goroutines).
	for range branches {
		<-done
	}
	<-doneFetch

	// Print output.
	// If there are multiple changes in the current branch, the output splits them out into separate sections,
	// in reverse commit order, to match git log output.
	//
	//	wbshadow 7a524a1..a496c1e (current branch, all mailed, 23 behind, tracking master)
	//	+ uncommitted changes
	//		Files unstaged:
	//			src/runtime/proc1.go
	//
	//	+ a496c1e https://go-review.googlesource.com/2064 (mailed)
	//		runtime: add missing write barriers in append's copy of slice data
	//
	//		Found with GODEBUG=wbshadow=1 mode.
	//		Eventually that will run automatically, but right now
	//		it still detects other missing write barriers.
	//
	//		Change-Id: Ic8624401d7c8225a935f719f96f2675c6f5c0d7c
	//
	//		Code-Review:
	//			+0 Austin Clements, Rick Hudson
	//		Files in this change:
	//			src/runtime/slice.go
	//
	//	+ 95390c7 https://go-review.googlesource.com/2061 (mailed)
	//		runtime: add GODEBUG wbshadow for finding missing write barriers
	//
	//		This is the detection code. It works well enough that I know of
	//		a handful of missing write barriers. However, those are subtle
	//		enough that I'll address them in separate followup CLs.
	//
	//		Change-Id: If863837308e7c50d96b5bdc7d65af4969bf53a6e
	//
	//		Code-Review:
	//			+0 Austin Clements, Rick Hudson
	//		Files in this change:
	//			src/runtime/extern.go
	//			src/runtime/malloc1.go
	//			src/runtime/malloc2.go
	//			src/runtime/mgc.go
	//			src/runtime/mgc0.go
	//			src/runtime/proc1.go
	//			src/runtime/runtime1.go
	//			src/runtime/runtime2.go
	//			src/runtime/stack1.go
	//
	// The first line only gives information that applies to the entire branch:
	// the name, the commit range, whether this is the current branch, whether
	// all the commits are mailed/submitted, how far behind, what remote branch
	// it is tracking.
	// The individual change sections have per-change information: the hash of that
	// commit, the URL on the Gerrit server, whether it is mailed/submitted, the list of
	// files in that commit. The uncommitted file modifications are shown as a separate
	// section, at the beginning, to fit better into the reverse commit order.
	//
	// The short view compresses the listing down to two lines per commit:
	//	wbshadow 7a524a1..a496c1e (current branch, all mailed, 23 behind, tracking master)
	//	+ uncommitted changes
	//		Files unstaged:
	//			src/runtime/proc1.go
	//	+ a496c1e runtime: add missing write barriers in append's copy of slice data (CL 2064, mailed)
	//	+ 95390c7 runtime: add GODEBUG wbshadow for finding missing write barriers (CL 2061, mailed)

	var buf bytes.Buffer
	printFileList := func(name string, list []string) {
		if len(list) == 0 {
			return
		}
		fmt.Fprintf(&buf, "\tFiles %s:\n", name)
		for _, file := range list {
			fmt.Fprintf(&buf, "\t\t%s\n", file)
		}
	}

	for _, b := range branches {
		if !b.current && b.commitsAhead == 0 {
			// Hide branches with no work on them.
			continue
		}

		fmt.Fprintf(&buf, "%s", b.Name)
		work := b.Pending()
		if len(work) > 0 {
			fmt.Fprintf(&buf, " %.7s..%s", b.branchpoint, work[0].ShortHash)
		}
		var tags []string
		if b.current {
			tags = append(tags, "current branch")
		}
		if allMailed(work) && len(work) > 0 {
			tags = append(tags, "all mailed")
		}
		if allSubmitted(work) && len(work) > 0 {
			tags = append(tags, "all submitted")
		}
		if n := b.CommitsBehind(); n > 0 {
			tags = append(tags, fmt.Sprintf("%d behind", n))
		}
		if br := b.OriginBranch(); br != "origin/master" && br != "origin/main" {
			tags = append(tags, "tracking "+strings.TrimPrefix(b.OriginBranch(), "origin/"))
		}
		if len(tags) > 0 {
			fmt.Fprintf(&buf, " (%s)", strings.Join(tags, ", "))
		}
		fmt.Fprintf(&buf, "\n")
		printed := false
		if text := b.errors(); text != "" {
			fmt.Fprintf(&buf, "\tERROR: %s\n", strings.Replace(strings.TrimSpace(text), "\n", "\n\t", -1))
			if !pendingShort {
				printed = true
				fmt.Fprintf(&buf, "\n")
			}
		}

		if b.current && len(b.staged)+len(b.unstaged)+len(b.untracked) > 0 {
			printed = true
			fmt.Fprintf(&buf, "+ uncommitted changes\n")
			printFileList("untracked", b.untracked)
			printFileList("unstaged", b.unstaged)
			printFileList("staged", b.staged)
			if !pendingShort {
				fmt.Fprintf(&buf, "\n")
			}
		}

		for _, c := range work {
			printed = true
			fmt.Fprintf(&buf, "+ ")
			formatCommit(&buf, c, pendingShort)
			if !pendingShort {
				printFileList("in this change", c.committed)
				fmt.Fprintf(&buf, "\n")
			}
		}
		if pendingShort || !printed {
			fmt.Fprintf(&buf, "\n")
		}
	}

	stdout().Write(buf.Bytes())
}

// formatCommit writes detailed information about c to w. c.g must
// have the "CURRENT_REVISION" (or "ALL_REVISIONS") and
// "DETAILED_LABELS" options set.
//
// If short is true, this writes a single line overview.
//
// If short is false, this writes detailed information about the
// commit and its Gerrit state.
func formatCommit(w io.Writer, c *Commit, short bool) {
	g := c.g
	msg := strings.TrimRight(c.Message, "\r\n")
	fmt.Fprintf(w, "%s", c.ShortHash)
	var tags []string
	if short {
		if i := strings.Index(msg, "\n"); i >= 0 {
			msg = msg[:i]
		}
		fmt.Fprintf(w, " %s", msg)
		if g.Number != 0 {
			tags = append(tags, fmt.Sprintf("CL %d%s", g.Number, codeReviewScores(g)))
		}
	} else {
		if g.Number != 0 {
			fmt.Fprintf(w, " %s/%d", auth.url, g.Number)
		}
	}
	if g.CurrentRevision == c.Hash {
		tags = append(tags, "mailed")
	}
	switch g.Status {
	case "MERGED":
		tags = append(tags, "submitted")
	case "ABANDONED":
		tags = append(tags, "abandoned")
	}
	if len(tags) > 0 {
		fmt.Fprintf(w, " (%s)", strings.Join(tags, ", "))
	}
	fmt.Fprintf(w, "\n")
	if short {
		return
	}

	fmt.Fprintf(w, "\t%s\n", strings.Replace(msg, "\n", "\n\t", -1))
	fmt.Fprintf(w, "\n")

	for _, name := range g.LabelNames() {
		label := g.Labels[name]
		minValue := 10000
		maxValue := -10000
		byScore := map[int][]string{}
		for _, x := range label.All {
			// Hide CL owner unless owner score is nonzero.
			if g.Owner != nil && x.ID == g.Owner.ID && x.Value == 0 {
				continue
			}
			byScore[x.Value] = append(byScore[x.Value], x.Name)
			if minValue > x.Value {
				minValue = x.Value
			}
			if maxValue < x.Value {
				maxValue = x.Value
			}
		}
		// Unless there are scores to report, do not show labels other than Code-Review.
		// This hides Run-TryBot and TryBot-Result.
		if minValue >= 0 && maxValue <= 0 && name != "Code-Review" {
			continue
		}
		fmt.Fprintf(w, "\t%s:\n", name)
		for score := maxValue; score >= minValue; score-- {
			who := byScore[score]
			if len(who) == 0 || score == 0 && name != "Code-Review" {
				continue
			}
			sort.Strings(who)
			fmt.Fprintf(w, "\t\t%+d %s\n", score, strings.Join(who, ", "))
		}
	}
}

// codeReviewScores reports the code review scores as tags for the short output.
//
// g must have the "DETAILED_LABELS" option set.
func codeReviewScores(g *GerritChange) string {
	label := g.Labels["Code-Review"]
	if label == nil {
		return ""
	}
	minValue := 10000
	maxValue := -10000
	for _, x := range label.All {
		if minValue > x.Value {
			minValue = x.Value
		}
		if maxValue < x.Value {
			maxValue = x.Value
		}
	}
	var scores string
	if minValue < 0 {
		scores += fmt.Sprintf(" %d", minValue)
	}
	if maxValue > 0 {
		scores += fmt.Sprintf(" %+d", maxValue)
	}
	return scores
}

// allMailed reports whether all commits in work have been posted to Gerrit.
func allMailed(work []*Commit) bool {
	for _, c := range work {
		if c.Hash != c.g.CurrentRevision {
			return false
		}
	}
	return true
}

// allSubmitted reports whether all commits in work have been submitted to the origin branch.
func allSubmitted(work []*Commit) bool {
	for _, c := range work {
		if c.g.Status != "MERGED" {
			return false
		}
	}
	return true
}

// errors returns any errors that should be displayed
// about the state of the current branch, diagnosing common mistakes.
func (b *Branch) errors() string {
	b.loadPending()
	var buf bytes.Buffer
	if haveGerrit() && !b.IsLocalOnly() && b.commitsAhead > 0 {
		fmt.Fprintf(&buf, "Branch contains %d commit%s not on origin/%s.\n", b.commitsAhead, suffix(b.commitsAhead, "s"), b.Name)
		fmt.Fprintf(&buf, "\tDo not commit directly to %s branch.\n", b.Name)
	}
	return buf.String()
}

// suffix returns an empty string if n == 1, s otherwise.
func suffix(n int, s string) string {
	if n == 1 {
		return ""
	}
	return s
}
