// 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"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os/user"
	"path/filepath"
	"runtime"
	"sort"
	"strings"
	"sync"
)

// auth holds cached data about authentication to Gerrit.
var auth struct {
	initialized bool

	host    string // "go.googlesource.com"
	url     string // "https://go-review.googlesource.com"
	project string // "go", "tools", "crypto", etc

	// Authentication information.
	// Either cookie name + value from git cookie file
	// or username and password from .netrc.
	cookieName  string
	cookieValue string
	user        string
	password    string
}

// loadGerritOriginMutex is used to control access when initializing auth
// in loadGerritOrigin, which can be called in parallel by "pending".
// We use a mutex rather than a sync.Once because the tests clear auth.
var loadGerritOriginMutex sync.Mutex

// loadGerritOrigin loads the Gerrit host name from the origin remote.
// This sets auth.{initialized,host,url,project}.
// If the origin remote does not appear to be a Gerrit server
// (is missing, is GitHub, is not https, has too many path elements),
// loadGerritOrigin dies.
func loadGerritOrigin() {
	loadGerritOriginMutex.Lock()
	defer loadGerritOriginMutex.Unlock()

	if auth.initialized {
		return
	}

	// Gerrit must be set, either explicitly via the code review config or
	// implicitly as Git's origin remote.
	origin := config()["gerrit"]
	originUrl := trim(cmdOutput("git", "config", "remote.origin.url"))

	err := loadGerritOriginInternal(origin, originUrl)
	if err != nil {
		dief("failed to load Gerrit origin: %v", err)
	}

	auth.initialized = true
}

// loadGerritOriginInternal does the work of loadGerritOrigin, just extracted out
// for easier testing.
func loadGerritOriginInternal(origin, remoteOrigin string) error {
	originUrl, err := url.Parse(remoteOrigin)
	if err != nil {
		return fmt.Errorf("failed to parse git's remote.origin.url %q as a URL: %v", remoteOrigin, err)
	} else {
		originUrl.User = nil
		remoteOrigin = originUrl.String()
	}
	hasGerritConfig := true
	if origin == "" {
		hasGerritConfig = false
		origin = remoteOrigin
	}
	if strings.Contains(origin, "github.com") {
		return fmt.Errorf("git origin must be a Gerrit host, not GitHub: %s", origin)
	}

	if googlesourceIndex := strings.Index(origin, ".googlesource.com"); googlesourceIndex >= 0 {
		if !strings.HasPrefix(origin, "https://") {
			return fmt.Errorf("git origin must be an https:// URL: %s", origin)
		}
		// https:// prefix and then one slash between host and top-level name
		if strings.Count(origin, "/") != 3 {
			return fmt.Errorf("git origin is malformed: %s", origin)
		}
		host := origin[len("https://"):strings.LastIndex(origin, "/")]

		// In the case of Google's Gerrit, host is go.googlesource.com
		// and apiURL uses go-review.googlesource.com, but the Gerrit
		// setup instructions do not write down a cookie explicitly for
		// go-review.googlesource.com, so we look for the non-review
		// host name instead.
		url := origin
		i := googlesourceIndex
		url = url[:i] + "-review" + url[i:]

		i = strings.LastIndex(url, "/")
		url, project := url[:i], url[i+1:]

		auth.host = host
		auth.url = url
		auth.project = project
		return nil
	}

	// Origin is not *.googlesource.com.
	//
	// If the Gerrit origin is set from the codereview.cfg file than we handle it
	// differently to allow for sub-path hosted Gerrit.
	auth.host = originUrl.Host
	if hasGerritConfig {
		if !strings.HasPrefix(remoteOrigin, origin) {
			return fmt.Errorf("Gerrit origin %q from %q different than git origin url %q", origin, configPath, originUrl)
		}

		auth.project = strings.Trim(strings.TrimPrefix(remoteOrigin, origin), "/")
		auth.url = origin
	} else {
		auth.project = strings.Trim(originUrl.Path, "/")
		auth.url = strings.TrimSuffix(remoteOrigin, originUrl.Path)
	}

	return nil
}

// testHomeDir is empty for normal use. During tests it may be set and used
// in place of the actual home directory. Tests may still need to
// set the HOME var for sub-processes such as git.
var testHomeDir = ""

func netrcName() string {
	// Git on Windows will look in $HOME\_netrc.
	if runtime.GOOS == "windows" {
		return "_netrc"
	}
	return ".netrc"
}

// loadAuth loads the authentication tokens for making API calls to
// the Gerrit origin host.
func loadAuth() {
	if auth.user != "" || auth.cookieName != "" {
		return
	}

	loadGerritOrigin()

	// First look in Git's http.cookiefile, which is where Gerrit
	// now tells users to store this information.
	if cookieFile, _ := trimErr(cmdOutputErr("git", "config", "--path", "--get-urlmatch", "http.cookiefile", auth.url)); cookieFile != "" {
		data, _ := ioutil.ReadFile(cookieFile)
		maxMatch := -1
		for _, line := range lines(string(data)) {
			f := strings.Split(line, "\t")
			if len(f) >= 7 && (f[0] == auth.host || strings.HasPrefix(f[0], ".") && strings.HasSuffix(auth.host, f[0])) {
				if len(f[0]) > maxMatch {
					auth.cookieName = f[5]
					auth.cookieValue = f[6]
					maxMatch = len(f[0])
				}
			}
		}
		if maxMatch > 0 {
			return
		}
	}

	// If not there, then look in $HOME/.netrc, which is where Gerrit
	// used to tell users to store the information, until the passwords
	// got so long that old versions of curl couldn't handle them.
	netrc := netrcName()
	homeDir := testHomeDir
	if homeDir == "" {
		usr, err := user.Current()
		if err != nil {
			dief("failed to get current user home directory to look for %q: %v", netrc, err)
		}
		homeDir = usr.HomeDir
	}
	data, _ := ioutil.ReadFile(filepath.Join(homeDir, netrc))
	for _, line := range lines(string(data)) {
		if i := strings.Index(line, "#"); i >= 0 {
			line = line[:i]
		}
		f := strings.Fields(line)
		if len(f) >= 6 && f[0] == "machine" && f[1] == auth.host && f[2] == "login" && f[4] == "password" {
			auth.user = f[3]
			auth.password = f[5]
			return
		}
	}

	dief("cannot find authentication info for %s", auth.host)
}

// gerritError is an HTTP error response served by Gerrit.
type gerritError struct {
	url        string
	statusCode int
	status     string
	body       string
}

func (e *gerritError) Error() string {
	if e.statusCode == http.StatusNotFound {
		return "change not found on Gerrit server"
	}

	extra := strings.TrimSpace(e.body)
	if extra != "" {
		extra = ": " + extra
	}
	return fmt.Sprintf("%s%s", e.status, extra)
}

// gerritAPI executes a GET or POST request to a Gerrit API endpoint.
// It uses GET when requestBody is nil, otherwise POST. If target != nil,
// gerritAPI expects to get a 200 response with a body consisting of an
// anti-xss line (]})' or some such) followed by JSON.
// If requestBody != nil, gerritAPI sets the Content-Type to application/json.
func gerritAPI(path string, requestBody []byte, target interface{}) error {
	// Strictly speaking, we might be able to use unauthenticated
	// access, by removing the /a/ from the URL, but that assumes
	// that all the information we care about is publicly visible.
	// Using authentication makes it possible for this to work with
	// non-public CLs or Gerrit hosts too.
	loadAuth()

	if !strings.HasPrefix(path, "/") {
		dief("internal error: gerritAPI called with malformed path")
	}

	url := auth.url + path
	method := "GET"
	var reader io.Reader
	if requestBody != nil {
		method = "POST"
		reader = bytes.NewReader(requestBody)
	}
	req, err := http.NewRequest(method, url, reader)
	if err != nil {
		return err
	}
	if requestBody != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	if auth.cookieName != "" {
		req.AddCookie(&http.Cookie{
			Name:  auth.cookieName,
			Value: auth.cookieValue,
		})
	} else {
		req.SetBasicAuth(auth.user, auth.password)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	if err != nil {
		return fmt.Errorf("reading response body: %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		return &gerritError{url, resp.StatusCode, resp.Status, string(body)}
	}

	if target != nil {
		i := bytes.IndexByte(body, '\n')
		if i < 0 {
			return fmt.Errorf("%s: malformed json response - bad header", url)
		}
		body = body[i:]
		if err := json.Unmarshal(body, target); err != nil {
			return fmt.Errorf("%s: malformed json response", url)
		}
	}
	return nil
}

// fullChangeID returns the unambigous Gerrit change ID for the commit c on branch b.
// The returned ID has the form project~originbranch~Ihexhexhexhexhex.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id for details.
func fullChangeID(b *Branch, c *Commit) string {
	loadGerritOrigin()
	return auth.project + "~" + strings.TrimPrefix(b.OriginBranch(), "origin/") + "~" + c.ChangeID
}

// readGerritChange reads the metadata about a change from the Gerrit server.
// The changeID should use the syntax project~originbranch~Ihexhexhexhexhex returned
// by fullChangeID. Using only Ihexhexhexhexhex will work provided it uniquely identifies
// a single change on the server.
// The changeID can have additional query parameters appended to it, as in "normalid?o=LABELS".
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id for details.
func readGerritChange(changeID string) (*GerritChange, error) {
	var c GerritChange
	err := gerritAPI("/a/changes/"+changeID, nil, &c)
	if err != nil {
		return nil, err
	}
	return &c, nil
}

// readGerritChanges is like readGerritChange but expects changeID
// to be a query parameter list like q=change:XXX&q=change:YYY&o=OPTIONS,
// and it expects to receive a JSON array of GerritChanges, not just one.
func readGerritChanges(query string) ([][]*GerritChange, error) {
	// The Gerrit server imposes a limit of at most 10 q= parameters.
	v, err := url.ParseQuery(query)
	if err != nil {
		return nil, err
	}
	var results []chan gerritChangeResult
	for len(v["q"]) > 0 {
		n := len(v["q"])
		if n > 10 {
			n = 10
		}
		all := v["q"]
		v["q"] = all[:n]
		query := v.Encode()
		v["q"] = all[n:]
		ch := make(chan gerritChangeResult, 1)
		go readGerritChangesBatch(query, n, ch)
		results = append(results, ch)
	}

	var c [][]*GerritChange
	for _, ch := range results {
		res := <-ch
		if res.err != nil {
			return nil, res.err
		}
		c = append(c, res.c...)
	}
	return c, nil
}

type gerritChangeResult struct {
	c   [][]*GerritChange
	err error
}

func readGerritChangesBatch(query string, n int, ch chan gerritChangeResult) {
	var c [][]*GerritChange
	// If there are multiple q=, the server sends back an array of arrays of results.
	// If there is a single q=, it only sends back an array of results; in that case
	// we need to do the wrapping ourselves.
	var arg interface{} = &c
	if n == 1 {
		c = append(c, nil)
		arg = &c[0]
	}
	err := gerritAPI("/a/changes/?"+query, nil, arg)
	if len(c) != n && err == nil {
		err = fmt.Errorf("gerrit result count mismatch")
	}
	ch <- gerritChangeResult{c, err}
}

// GerritChange is the JSON struct returned by a Gerrit CL query.
type GerritChange struct {
	ID              string
	Project         string
	Branch          string
	ChangeId        string `json:"change_id"`
	Subject         string
	Status          string
	Created         string
	Updated         string
	Insertions      int
	Deletions       int
	Number          int `json:"_number"`
	Owner           *GerritAccount
	Labels          map[string]*GerritLabel
	CurrentRevision string `json:"current_revision"`
	Revisions       map[string]*GerritRevision
	Messages        []*GerritMessage
}

// LabelNames returns the label names for the change, in lexicographic order.
func (g *GerritChange) LabelNames() []string {
	var names []string
	for name := range g.Labels {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

// GerritMessage is the JSON struct for a Gerrit MessageInfo.
type GerritMessage struct {
	Author struct {
		Name string
	}
	Message string
}

// GerritLabel is the JSON struct for a Gerrit LabelInfo.
type GerritLabel struct {
	Optional bool
	Blocking bool
	Approved *GerritAccount
	Rejected *GerritAccount
	All      []*GerritApproval
}

// GerritAccount is the JSON struct for a Gerrit AccountInfo.
type GerritAccount struct {
	ID       int `json:"_account_id"`
	Name     string
	Email    string
	Username string
}

// GerritApproval is the JSON struct for a Gerrit ApprovalInfo.
type GerritApproval struct {
	GerritAccount
	Value int
	Date  string
}

// GerritRevision is the JSON struct for a Gerrit RevisionInfo.
type GerritRevision struct {
	Number int `json:"_number"`
	Ref    string
	Fetch  map[string]*GerritFetch
}

// GerritFetch is the JSON struct for a Gerrit FetchInfo
type GerritFetch struct {
	URL string
	Ref string
}
