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

var pendingLocal bool // -l flag, use only local operations (no network)

// 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
	g         *GerritChange // state loaded from Gerrit
	gerr      error         // error loading state from Gerrit
	current   bool          // is this the current branch?
	committed []string      // files committed on this 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()
	}
	if b.parentHash != "" && b.commitHash != "" {
		b.committed = getLines("git", "diff", "--name-only", b.parentHash, b.commitHash)
	}
	if !pendingLocal {
		b.g, b.gerr = b.GerritChange("DETAILED_LABELS", "CURRENT_REVISION", "MESSAGES", "DETAILED_ACCOUNTS")
	}
}

func pending(args []string) {
	flags.BoolVar(&pendingLocal, "l", false, "use only local information - no network operations")
	flags.Parse(args)
	if len(flags.Args()) > 0 {
		fmt.Fprintf(os.Stderr, "Usage: %s pending %s [-l]\n", os.Args[0], globalFlags)
		os.Exit(2)
	}

	// Fetch info about remote changes, so that we can say which branches need sync.
	if !pendingLocal {
		run("git", "fetch", "-q")
		http.DefaultClient.Timeout = 5 * time.Second
	}

	// Build list of pendingBranch structs to be filled in.
	current := CurrentBranch().Name
	var branches []*pendingBranch
	for _, b := range LocalBranches() {
		branches = append(branches, &pendingBranch{Branch: b, current: b.Name == current})
	}

	// 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 {
				b.load()
				done <- true
			}
		}()
	}

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

	// Print output, like:
	//	pending d8fcb99 https://go-review.googlesource.com/1620 (current branch, 1 behind)
	//		git-codereview: expand pending output
	//
	//		for pending:
	//		- show full commit message
	//		- show information about being behind upstream
	//		- show list of modified files
	//		- for current branch, show staged, unstaged, untracked files
	//		- warn about being ahead of upstream on master
	//		- warn about being multiple commits ahead of upstream
	//
	//		- add same warnings to change
	//		- add change -a (mostly unrelated, but prompted by this work)
	//
	//		Change-Id: Ie480ba5b66cc07faffca421ee6c9623d35204696
	//
	//		Code-Review:
	//			+2 Andrew Gerrand, Rob Pike
	//		Files in this change:
	//			git-codereview/api.go
	//			git-codereview/branch.go
	//			git-codereview/change.go
	//			git-codereview/pending.go
	//			git-codereview/review.go
	//			git-codereview/submit.go
	//			git-codereview/sync.go
	//		Files untracked:
	//			git-codereview/doc.go
	//			git-codereview/savedmail.go.txt
	//
	var buf bytes.Buffer
	for _, b := range branches {
		if !b.current && b.commitsAhead == 0 {
			// Hide branches with no work on them.
			continue
		}

		fmt.Fprintf(&buf, "%s", b.Name)
		if b.shortCommitHash != "" {
			fmt.Fprintf(&buf, " %s", b.shortCommitHash)
		}
		if b.g != nil && b.g.Number != 0 {
			fmt.Fprintf(&buf, " %s/%d", auth.url, b.g.Number)
		}
		var tags []string
		if b.current {
			tags = append(tags, "current branch")
		}
		if b.g != nil && b.g.CurrentRevision == b.commitHash {
			tags = append(tags, "mailed")
		}
		if b.g != nil && b.g.Status == "MERGED" {
			tags = append(tags, "submitted")
		}
		if b.commitsBehind > 0 {
			tags = append(tags, fmt.Sprintf("%d behind", b.commitsBehind))
		}
		if len(tags) > 0 {
			fmt.Fprintf(&buf, " (%s)", strings.Join(tags, ", "))
		}
		fmt.Fprintf(&buf, "\n")
		if text := b.errors(); text != "" {
			fmt.Fprintf(&buf, "\tERROR: %s\n\n", strings.Replace(strings.TrimSpace(text), "\n", "\n\t", -1))
		}
		if b.message != "" {
			msg := strings.TrimRight(b.message, "\r\n")
			fmt.Fprintf(&buf, "\t%s\n", strings.Replace(msg, "\n", "\n\t", -1))
			fmt.Fprintf(&buf, "\n")
		}
		if b.g != nil {
			for _, name := range b.g.LabelNames() {
				label := b.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 b.g.Owner != nil && x.ID == b.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
					}
				}
				fmt.Fprintf(&buf, "\t%s:\n", name)
				for score := maxValue; score >= minValue; score-- {
					who := byScore[score]
					if len(who) == 0 {
						continue
					}
					sort.Strings(who)
					fmt.Fprintf(&buf, "\t\t%+d %s\n", score, strings.Join(who, ", "))
				}
			}
		}
		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)
			}
		}
		printFileList("in this change", b.committed)
		printFileList("staged", b.staged)
		printFileList("unstaged", b.unstaged)
		printFileList("untracked", b.untracked)

		fmt.Fprintf(&buf, "\n")
	}

	if stdoutTrap != nil {
		stdoutTrap.Write(buf.Bytes())
	} else {
		os.Stdout.Write(buf.Bytes())
	}
}

// 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 !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)
	} else if b.commitsAhead > 1 {
		fmt.Fprintf(&buf, "Branch contains %d commits not on origin/%s.\n", b.commitsAhead, b.OriginBranch())
		fmt.Fprintf(&buf, "\tThere should be at most one.\n")
		fmt.Fprintf(&buf, "\tUse 'git change', not 'git commit'.\n")
		fmt.Fprintf(&buf, "\tRun 'git log %s..%s' to list commits.\n", b.OriginBranch(), 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
}
