// Copyright 2015 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 gerrit contains code to interact with Gerrit servers.
//
// The API is not subject to the Go 1 compatibility promise and may change at
// any time.
package gerrit

import (
	"bufio"
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"time"
)

// Client is a Gerrit client.
type Client struct {
	url  string // URL prefix, e.g. "https://go-review.googlesource.com" (without trailing slash)
	auth Auth

	// HTTPClient optionally specifies an HTTP client to use
	// instead of http.DefaultClient.
	HTTPClient *http.Client
}

// NewClient returns a new Gerrit client with the given URL prefix
// and authentication mode.
// The url should be just the scheme and hostname. For example, "https://go-review.googlesource.com".
// If auth is nil, a default is used, or requests are made unauthenticated.
func NewClient(url string, auth Auth) *Client {
	if auth == nil {
		// TODO(bradfitz): use GitCookies auth, once that exists
		auth = NoAuth
	}
	return &Client{
		url:  strings.TrimSuffix(url, "/"),
		auth: auth,
	}
}

func (c *Client) httpClient() *http.Client {
	if c.HTTPClient != nil {
		return c.HTTPClient
	}
	return http.DefaultClient
}

// HTTPError is the error type returned when a Gerrit API call does not return
// the expected status.
type HTTPError struct {
	Res     *http.Response
	Body    []byte // 4KB prefix
	BodyErr error  // any error reading Body
}

func (e *HTTPError) Error() string {
	return fmt.Sprintf("HTTP status %s; %s", e.Res.Status, e.Body)
}

// doArg is one of urlValues, reqBody, or wantResStatus
type doArg interface {
	isDoArg()
}

type wantResStatus int

func (wantResStatus) isDoArg() {}

type reqBody struct{ body interface{} }

func (reqBody) isDoArg() {}

type urlValues url.Values

func (urlValues) isDoArg() {}

func (c *Client) do(ctx context.Context, dst interface{}, method, path string, opts ...doArg) error {
	var arg url.Values
	var body interface{}
	var wantStatus = http.StatusOK
	for _, opt := range opts {
		switch opt := opt.(type) {
		case wantResStatus:
			wantStatus = int(opt)
		case reqBody:
			body = opt.body
		case urlValues:
			arg = url.Values(opt)
		default:
			panic(fmt.Sprintf("internal error; unsupported type %T", opt))
		}
	}

	var bodyr io.Reader
	var contentType string
	if body != nil {
		v, err := json.MarshalIndent(body, "", "  ")
		if err != nil {
			return err
		}
		bodyr = bytes.NewReader(v)
		contentType = "application/json"
	}
	// slashA is either "/a" (for authenticated requests) or "" for unauthenticated.
	// See https://gerrit-review.googlesource.com/Documentation/rest-api.html#authentication
	slashA := "/a"
	if _, ok := c.auth.(noAuth); ok {
		slashA = ""
	}
	var err error
	u := c.url + slashA + path
	if arg != nil {
		u += "?" + arg.Encode()
	}
	req, err := http.NewRequest(method, u, bodyr)
	if err != nil {
		return err
	}
	if contentType != "" {
		req.Header.Set("Content-Type", contentType)
	}
	c.auth.setAuth(c, req)
	res, err := c.httpClient().Do(req.WithContext(ctx))
	if err != nil {
		return err
	}
	defer res.Body.Close()

	if res.StatusCode != wantStatus {
		body, err := ioutil.ReadAll(io.LimitReader(res.Body, 4<<10))
		return &HTTPError{res, body, err}
	}

	// The JSON response begins with an XSRF-defeating header
	// like ")]}\n". Read that and skip it.
	br := bufio.NewReader(res.Body)
	if _, err := br.ReadSlice('\n'); err != nil {
		return err
	}
	return json.NewDecoder(br).Decode(dst)
}

// Possible values for the ChangeInfo Status field.
const (
	ChangeStatusNew       = "NEW"
	ChangeStatusAbandoned = "ABANDONED"
	ChangeStatusMerged    = "MERGED"
)

// ChangeInfo is a Gerrit data structure.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
type ChangeInfo struct {
	// ID is the ID of the change in the format
	// "'<project>~<branch>~<Change-Id>'", where 'project',
	// 'branch' and 'Change-Id' are URL encoded. For 'branch' the
	// refs/heads/ prefix is omitted.
	ID           string `json:"id"`
	ChangeNumber int    `json:"_number"`
	ChangeID     string `json:"change_id"`

	Project string `json:"project"`

	// Branch is the name of the target branch.
	// The refs/heads/ prefix is omitted.
	Branch string `json:"branch"`

	Topic    string       `json:"topic"`
	Assignee *AccountInfo `json:"assignee"`
	Hashtags []string     `json:"hashtags"`

	// Subject is the subject of the change
	// (the header line of the commit message).
	Subject string `json:"subject"`

	// Status is the status of the change (NEW, SUBMITTED, MERGED,
	// ABANDONED, DRAFT).
	Status string `json:"status"`

	Created    TimeStamp    `json:"created"`
	Updated    TimeStamp    `json:"updated"`
	Submitted  TimeStamp    `json:"submitted"`
	Submitter  *AccountInfo `json:"submitter"`
	SubmitType string       `json:"submit_type"`

	// Mergeable indicates whether the change can be merged.
	// It is not set for already-merged changes,
	// nor if the change is untested, nor if the
	// SKIP_MERGEABLE option has been set.
	Mergeable bool `json:"mergeable"`

	// Submittable indicates whether the change can be submitted.
	// It is only set if requested, using the "SUBMITTABLE" option.
	Submittable bool `json:"submittable"`

	// Insertions and Deletions count inserted and deleted lines.
	Insertions int `json:"insertions"`
	Deletions  int `json:"deletions"`

	// CurrentRevision is the commit ID of the current patch set
	// of this change.  This is only set if the current revision
	// is requested or if all revisions are requested (fields
	// "CURRENT_REVISION" or "ALL_REVISIONS").
	CurrentRevision string `json:"current_revision"`

	// Revisions maps a commit ID of the patch set to a
	// RevisionInfo entity.
	//
	// Only set if the current revision is requested (in which
	// case it will only contain a key for the current revision)
	// or if all revisions are requested.
	Revisions map[string]RevisionInfo `json:"revisions"`

	// Owner is the author of the change.
	// The details are only filled in if field "DETAILED_ACCOUNTS" is requested.
	Owner *AccountInfo `json:"owner"`

	// Messages are included if field "MESSAGES" is requested.
	Messages []ChangeMessageInfo `json:"messages"`

	// Labels maps label names to LabelInfo entries.
	Labels map[string]LabelInfo `json:"labels"`

	// ReviewerUpdates are included if field "REVIEWER_UPDATES" is requested.
	ReviewerUpdates []ReviewerUpdateInfo `json:"reviewer_updates"`

	// Reviewers maps reviewer state ("REVIEWER", "CC", "REMOVED")
	// to a list of accounts.
	// REVIEWER lists users with at least one non-zero vote on the change.
	// CC lists users added to the change who has not voted.
	// REMOVED lists users who were previously reviewers on the change
	// but who have been removed.
	// Reviewers is only included if "DETAILED_LABELS" is requested.
	Reviewers map[string][]*AccountInfo `json:"reviewers"`

	// WorkInProgress indicates that the change is marked as a work in progress.
	// (This means it is not yet ready for review, but it is still publicly visible.)
	WorkInProgress bool `json:"work_in_progress"`

	// HasReviewStarted indicates whether the change has ever been marked
	// ready for review in the past (not as a work in progress).
	HasReviewStarted bool `json:"has_review_started"`

	// RevertOf lists the numeric Change-Id of the change that this change reverts.
	RevertOf int `json:"revert_of"`

	// MoreChanges is set on the last change from QueryChanges if
	// the result set is truncated by an 'n' parameter.
	MoreChanges bool `json:"_more_changes"`
}

// ReviewerUpdateInfo is a Gerrit data structure.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-update-info
type ReviewerUpdateInfo struct {
	Updated   TimeStamp    `json:"updated"`
	UpdatedBy *AccountInfo `json:"updated_by"`
	Reviewer  *AccountInfo `json:"reviewer"`
	State     string       // "REVIEWER", "CC", or "REMOVED"
}

// AccountInfo is a Gerrit data structure. It's used both for getting the details
// for a single account, as well as for querying multiple accounts.
type AccountInfo struct {
	NumericID int64  `json:"_account_id"`
	Name      string `json:"name,omitempty"`
	Email     string `json:"email,omitempty"`
	Username  string `json:"username,omitempty"`

	// MoreAccounts is set on the last account from QueryAccounts if
	// the result set is truncated by an 'n' parameter (or has more).
	MoreAccounts bool `json:"_more_accounts"`

	// TODO: "avatars" is also returned, but not added here yet (add if required)
}

func (ai *AccountInfo) Equal(v *AccountInfo) bool {
	if ai == nil || v == nil {
		return false
	}
	return ai.NumericID == v.NumericID
}

type ChangeMessageInfo struct {
	ID             string       `json:"id"`
	Author         *AccountInfo `json:"author"`
	Time           TimeStamp    `json:"date"`
	Message        string       `json:"message"`
	Tag            string       `json:"tag,omitempty"`
	RevisionNumber int          `json:"_revision_number"`
}

// The LabelInfo entity contains information about a label on a
// change, always corresponding to the current patch set.
//
// There are two options that control the contents of LabelInfo:
// LABELS and DETAILED_LABELS.
//
// For a quick summary of the state of labels, use LABELS.
//
// For detailed information about labels, including exact numeric
// votes for all users and the allowed range of votes for the current
// user, use DETAILED_LABELS.
type LabelInfo struct {
	// Optional means the label may be set, but it’s neither
	// necessary for submission nor does it block submission if
	// set.
	Optional bool `json:"optional"`

	// Fields set by LABELS field option:

	All []ApprovalInfo `json:"all"`
}

type ApprovalInfo struct {
	AccountInfo
	Value int       `json:"value"`
	Date  TimeStamp `json:"date"`
}

// The RevisionInfo entity contains information about a patch set. Not
// all fields are returned by default. Additional fields can be
// obtained by adding o parameters as described at:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
type RevisionInfo struct {
	Draft             bool                  `json:"draft"`
	PatchSetNumber    int                   `json:"_number"`
	Created           TimeStamp             `json:"created"`
	Uploader          *AccountInfo          `json:"uploader"`
	Ref               string                `json:"ref"`
	Fetch             map[string]*FetchInfo `json:"fetch"`
	Commit            *CommitInfo           `json:"commit"`
	Files             map[string]*FileInfo  `json:"files"`
	CommitWithFooters string                `json:"commit_with_footers"`
	Kind              string                `json:"kind"`
	// TODO: more
}

type CommitInfo struct {
	Author    GitPersonInfo `json:"author"`
	Committer GitPersonInfo `json:"committer"`
	CommitID  string        `json:"commit"`
	Subject   string        `json:"subject"`
	Message   string        `json:"message"`
	Parents   []CommitInfo  `json:"parents"`
}

type GitPersonInfo struct {
	Name     string    `json:"name"`
	Email    string    `json:"Email"`
	Date     TimeStamp `json:"date"`
	TZOffset int       `json:"tz"`
}

func (gpi *GitPersonInfo) Equal(v *GitPersonInfo) bool {
	if gpi == nil {
		if gpi != v {
			return false
		}
		return true
	}
	return gpi.Name == v.Name && gpi.Email == v.Email && gpi.Date.Equal(v.Date) &&
		gpi.TZOffset == v.TZOffset
}

// Possible values for the FileInfo Status field.
const (
	FileInfoAdded     = "A"
	FileInfoDeleted   = "D"
	FileInfoRenamed   = "R"
	FileInfoCopied    = "C"
	FileInfoRewritten = "W"
)

type FileInfo struct {
	Status        string `json:"status"`
	Binary        bool   `json:"binary"`
	OldPath       string `json:"old_path"`
	LinesInserted int    `json:"lines_inserted"`
	LinesDeleted  int    `json:"lines_deleted"`
}

type FetchInfo struct {
	URL      string            `json:"url"`
	Ref      string            `json:"ref"`
	Commands map[string]string `json:"commands"`
}

// QueryChangesOpt are options for QueryChanges.
type QueryChangesOpt struct {
	// N is the number of results to return.
	// If 0, the 'n' parameter is not sent to Gerrit.
	N int

	// Start is the number of results to skip (useful in pagination).
	// To figure out if there are more results, the last ChangeInfo struct
	// in the last call to QueryChanges will have the field MoreAccounts=true.
	// If 0, the 'S' parameter is not sent to Gerrit.
	Start int

	// Fields are optional fields to also return.
	// Example strings include "ALL_REVISIONS", "LABELS", "MESSAGES".
	// For a complete list, see:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
	Fields []string
}

func condInt(n int) []string {
	if n != 0 {
		return []string{strconv.Itoa(n)}
	}
	return nil
}

// QueryChanges queries changes. The q parameter is a Gerrit search query.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
// For the query syntax, see https://gerrit-review.googlesource.com/Documentation/user-search.html#_search_operators
func (c *Client) QueryChanges(ctx context.Context, q string, opts ...QueryChangesOpt) ([]*ChangeInfo, error) {
	var opt QueryChangesOpt
	switch len(opts) {
	case 0:
	case 1:
		opt = opts[0]
	default:
		return nil, errors.New("only 1 option struct supported")
	}
	var changes []*ChangeInfo
	err := c.do(ctx, &changes, "GET", "/changes/", urlValues{
		"q": {q},
		"n": condInt(opt.N),
		"o": opt.Fields,
		"S": condInt(opt.Start),
	})
	return changes, err
}

// GetChange returns information about a single change.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-change
// If the change doesn't exist, the error will be ErrChangeNotExist.
func (c *Client) GetChange(ctx context.Context, changeID string, opts ...QueryChangesOpt) (*ChangeInfo, error) {
	var opt QueryChangesOpt
	switch len(opts) {
	case 0:
	case 1:
		opt = opts[0]
	default:
		return nil, errors.New("only 1 option struct supported")
	}
	change := new(ChangeInfo)
	err := c.do(ctx, change, "GET", "/changes/"+changeID, urlValues{
		"n": condInt(opt.N),
		"o": opt.Fields,
	})
	if he, ok := err.(*HTTPError); ok && he.Res.StatusCode == 404 {
		return nil, ErrChangeNotExist
	}
	return change, err
}

// GetChangeDetail retrieves a change with labels, detailed labels, detailed
// accounts, and messages.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-change-detail
func (c *Client) GetChangeDetail(ctx context.Context, changeID string, opts ...QueryChangesOpt) (*ChangeInfo, error) {
	var opt QueryChangesOpt
	switch len(opts) {
	case 0:
	case 1:
		opt = opts[0]
	default:
		return nil, errors.New("only 1 option struct supported")
	}
	var change ChangeInfo
	err := c.do(ctx, &change, "GET", "/changes/"+changeID+"/detail", urlValues{
		"o": opt.Fields,
	})
	if err != nil {
		return nil, err
	}
	return &change, nil
}

// ListChangeComments retrieves a map of published comments for the given change ID.
// The map key is the file path (such as "maintner/git_test.go" or "/PATCHSET_LEVEL").
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-change-comments.
func (c *Client) ListChangeComments(ctx context.Context, changeID string) (map[string][]CommentInfo, error) {
	var m map[string][]CommentInfo
	if err := c.do(ctx, &m, "GET", "/changes/"+changeID+"/comments"); err != nil {
		return nil, err
	}
	return m, nil
}

// CommentInfo contains information about an inline comment.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-info.
type CommentInfo struct {
	PatchSet int          `json:"patch_set,omitempty"`
	ID       string       `json:"id"`
	Path     string       `json:"path,omitempty"`
	Message  string       `json:"message,omitempty"`
	Updated  TimeStamp    `json:"updated"`
	Author   *AccountInfo `json:"author,omitempty"`
}

// ListFiles retrieves a map of filenames to FileInfo's for the given change ID and revision.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-files
func (c *Client) ListFiles(ctx context.Context, changeID, revision string) (map[string]*FileInfo, error) {
	var m map[string]*FileInfo
	if err := c.do(ctx, &m, "GET", "/changes/"+changeID+"/revisions/"+revision+"/files"); err != nil {
		return nil, err
	}
	return m, nil
}

// ReviewInput contains information for adding a review to a revision.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-input
type ReviewInput struct {
	Message string         `json:"message,omitempty"`
	Labels  map[string]int `json:"labels,omitempty"`

	// Comments contains optional per-line comments to post.
	// The map key is a file path (such as "src/foo/bar.go").
	Comments map[string][]CommentInput `json:"comments,omitempty"`

	// Reviewers optionally specifies new reviewers to add to the change.
	Reviewers []ReviewerInput `json:"reviewers,omitempty"`
}

// ReviewerInput contains information for adding a reviewer to a change.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#reviewer-input
type ReviewerInput struct {
	// Reviewer is the ID of the account to be added as reviewer.
	// See https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-id
	Reviewer string `json:"reviewer"`
	State    string `json:"state,omitempty"` // REVIEWER or CC (default: REVIEWER)
}

// CommentInput contains information for creating an inline comment.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-input
type CommentInput struct {
	Line    int    `json:"line"`
	Message string `json:"message"`

	// TODO(haya14busa): more, as needed.
}

type reviewInfo struct {
	Labels map[string]int `json:"labels,omitempty"`
}

// SetReview leaves a message on a change and/or modifies labels.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#set-review
// The changeID is https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
// The revision is https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#revision-id
func (c *Client) SetReview(ctx context.Context, changeID, revision string, review ReviewInput) error {
	var res reviewInfo
	return c.do(ctx, &res, "POST", fmt.Sprintf("/changes/%s/revisions/%s/review", changeID, revision),
		reqBody{review})
}

// ReviewerInfo contains information about reviewers of a change.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#reviewer-info
type ReviewerInfo struct {
	AccountInfo
	Approvals map[string]string `json:"approvals"`
}

// ListReviewers returns all reviewers on a change.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-reviewers
// The changeID is https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) ListReviewers(ctx context.Context, changeID string) ([]ReviewerInfo, error) {
	var res []ReviewerInfo
	if err := c.do(ctx, &res, "GET", fmt.Sprintf("/changes/%s/reviewers", changeID)); err != nil {
		return nil, err
	}
	return res, nil
}

// HashtagsInput is the request body used when modifying a CL's hashtags.
//
// See https://gerrit-documentation.storage.googleapis.com/Documentation/2.15.1/rest-api-changes.html#hashtags-input
type HashtagsInput struct {
	Add    []string `json:"add"`
	Remove []string `json:"remove"`
}

// SetHashtags modifies the hashtags for a CL, supporting both adding
// and removing hashtags in one request. On success it returns the new
// set of hashtags.
//
// See https://gerrit-documentation.storage.googleapis.com/Documentation/2.15.1/rest-api-changes.html#set-hashtags
func (c *Client) SetHashtags(ctx context.Context, changeID string, hashtags HashtagsInput) ([]string, error) {
	var res []string
	err := c.do(ctx, &res, "POST", fmt.Sprintf("/changes/%s/hashtags", changeID), reqBody{hashtags})
	return res, err
}

// AddHashtags is a wrapper around SetHashtags that only supports adding tags.
func (c *Client) AddHashtags(ctx context.Context, changeID string, tags ...string) ([]string, error) {
	return c.SetHashtags(ctx, changeID, HashtagsInput{Add: tags})
}

// RemoveHashtags is a wrapper around SetHashtags that only supports removing tags.
func (c *Client) RemoveHashtags(ctx context.Context, changeID string, tags ...string) ([]string, error) {
	return c.SetHashtags(ctx, changeID, HashtagsInput{Remove: tags})
}

// GetHashtags returns a CL's current hashtags.
//
// See https://gerrit-documentation.storage.googleapis.com/Documentation/2.15.1/rest-api-changes.html#get-hashtags
func (c *Client) GetHashtags(ctx context.Context, changeID string) ([]string, error) {
	var res []string
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/changes/%s/hashtags", changeID))
	return res, err
}

// AbandonChange abandons the given change.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#abandon-change
// The changeID is https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
// The input for the call is https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#abandon-input
func (c *Client) AbandonChange(ctx context.Context, changeID string, message ...string) error {
	var msg string
	if len(message) > 1 {
		panic("invalid use of multiple message inputs")
	}
	if len(message) == 1 {
		msg = message[0]
	}
	b := struct {
		Message string `json:"message,omitempty"`
	}{msg}
	var change ChangeInfo
	return c.do(ctx, &change, "POST", "/changes/"+changeID+"/abandon", reqBody{&b})
}

// ProjectInput contains the options for creating a new project.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#project-input
type ProjectInput struct {
	Parent      string `json:"parent,omitempty"`
	Description string `json:"description,omitempty"`
	SubmitType  string `json:"submit_type,omitempty"`

	CreateNewChangeForAllNotInTarget string `json:"create_new_change_for_all_not_in_target,omitempty"`

	// TODO(bradfitz): more, as needed.
}

// ProjectInfo is information about a Gerrit project.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#project-info
type ProjectInfo struct {
	ID          string            `json:"id"`
	Name        string            `json:"name"`
	Parent      string            `json:"parent"`
	CloneURL    string            `json:"clone_url"`
	Description string            `json:"description"`
	State       string            `json:"state"`
	Branches    map[string]string `json:"branches"`
}

// ListProjects returns the server's active projects.
//
// The returned slice is sorted by project ID and excludes the "All-Projects" project.
//
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#list-projects
func (c *Client) ListProjects(ctx context.Context) ([]ProjectInfo, error) {
	var res map[string]ProjectInfo
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/projects/"))
	if err != nil {
		return nil, err
	}
	var ret []ProjectInfo
	for name, pi := range res {
		if name == "All-Projects" {
			continue
		}
		if pi.State != "ACTIVE" {
			continue
		}
		ret = append(ret, pi)
	}
	sort.Slice(ret, func(i, j int) bool { return ret[i].ID < ret[j].ID })
	return ret, nil
}

// CreateProject creates a new project.
func (c *Client) CreateProject(ctx context.Context, name string, p ...ProjectInput) (ProjectInfo, error) {
	var pi ProjectInput
	if len(p) > 1 {
		panic("invalid use of multiple project inputs")
	}
	if len(p) == 1 {
		pi = p[0]
	}
	var res ProjectInfo
	err := c.do(ctx, &res, "PUT", fmt.Sprintf("/projects/%s", name), reqBody{&pi}, wantResStatus(http.StatusCreated))
	return res, err
}

// ErrProjectNotExist is returned when a project doesn't exist.
// It is not necessarily returned unless a method is documented as
// returning it.
var ErrProjectNotExist = errors.New("gerrit: requested project does not exist")

// ErrChangeNotExist is returned when a change doesn't exist.
// It is not necessarily returned unless a method is documented as
// returning it.
var ErrChangeNotExist = errors.New("gerrit: requested change does not exist")

// GetProjectInfo returns info about a project.
// If the project doesn't exist, the error will be ErrProjectNotExist.
func (c *Client) GetProjectInfo(ctx context.Context, name string) (ProjectInfo, error) {
	var res ProjectInfo
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/projects/%s", name))
	if he, ok := err.(*HTTPError); ok && he.Res.StatusCode == 404 {
		return res, ErrProjectNotExist
	}
	return res, err
}

// BranchInfo is information about a branch.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#branch-info
type BranchInfo struct {
	Ref       string `json:"ref"`
	Revision  string `json:"revision"`
	CanDelete bool   `json:"can_delete"`
}

// GetProjectBranches returns the branches for the project name. The branches are stored in a map
// keyed by reference.
func (c *Client) GetProjectBranches(ctx context.Context, name string) (map[string]BranchInfo, error) {
	var res []BranchInfo
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/projects/%s/branches/", name))
	if err != nil {
		return nil, err
	}
	m := map[string]BranchInfo{}
	for _, bi := range res {
		m[bi.Ref] = bi
	}
	return m, nil
}

// WebLinkInfo is information about a web link.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#web-link-info
type WebLinkInfo struct {
	Name     string `json:"name"`
	URL      string `json:"url"`
	ImageURL string `json:"image_url"`
}

func (wli *WebLinkInfo) Equal(v *WebLinkInfo) bool {
	if wli == nil || v == nil {
		return false
	}
	return wli.Name == v.Name && wli.URL == v.URL && wli.ImageURL == v.ImageURL
}

// TagInfo is information about a tag.
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#tag-info
type TagInfo struct {
	Ref       string         `json:"ref"`
	Revision  string         `json:"revision"`
	Object    string         `json:"object,omitempty"`
	Message   string         `json:"message,omitempty"`
	Tagger    *GitPersonInfo `json:"tagger,omitempty"`
	Created   TimeStamp      `json:"created,omitempty"`
	CanDelete bool           `json:"can_delete"`
	WebLinks  []WebLinkInfo  `json:"web_links,omitempty"`
}

func (ti *TagInfo) Equal(v *TagInfo) bool {
	if ti == nil || v == nil {
		return false
	}
	if ti.Ref != v.Ref || ti.Revision != v.Revision || ti.Object != v.Object ||
		ti.Message != v.Message || !ti.Created.Equal(v.Created) || ti.CanDelete != v.CanDelete {
		return false
	}
	if !ti.Tagger.Equal(v.Tagger) {
		return false
	}
	if len(ti.WebLinks) != len(v.WebLinks) {
		return false
	}
	for i := range ti.WebLinks {
		if !ti.WebLinks[i].Equal(&v.WebLinks[i]) {
			return false
		}
	}
	return true
}

// GetProjectTags returns the tags for the project name. The tags are stored in a map keyed by
// reference.
func (c *Client) GetProjectTags(ctx context.Context, name string) (map[string]TagInfo, error) {
	var res []TagInfo
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/projects/%s/tags/", name))
	if err != nil {
		return nil, err
	}
	m := map[string]TagInfo{}
	for _, ti := range res {
		m[ti.Ref] = ti
	}
	return m, nil
}

// GetAccountInfo gets the specified account's information from Gerrit.
// For the API call, see https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#get-account
// The accountID is https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-id
//
// Note that getting "self" is a good way to validate host access, since it only requires peeker
// access to the host, not to any particular repository.
func (c *Client) GetAccountInfo(ctx context.Context, accountID string) (AccountInfo, error) {
	var res AccountInfo
	err := c.do(ctx, &res, "GET", fmt.Sprintf("/accounts/%s", accountID))
	return res, err
}

// QueryAccountsOpt are options for QueryAccounts.
type QueryAccountsOpt struct {
	// N is the number of results to return.
	// If 0, the 'n' parameter is not sent to Gerrit.
	N int

	// Start is the number of results to skip (useful in pagination).
	// To figure out if there are more results, the last AccountInfo struct
	// in the last call to QueryAccounts will have the field MoreAccounts=true.
	// If 0, the 'S' parameter is not sent to Gerrit.
	Start int

	// Fields are optional fields to also return.
	// Example strings include "DETAILS", "ALL_EMAILS".
	// By default, only the account IDs are returned.
	// For a complete list, see:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#query-account
	Fields []string
}

// QueryAccounts queries accounts. The q parameter is a Gerrit search query.
// For the API call and query syntax, see https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#query-account
func (c *Client) QueryAccounts(ctx context.Context, q string, opts ...QueryAccountsOpt) ([]*AccountInfo, error) {
	var opt QueryAccountsOpt
	switch len(opts) {
	case 0:
	case 1:
		opt = opts[0]
	default:
		return nil, errors.New("only 1 option struct supported")
	}
	var changes []*AccountInfo
	err := c.do(ctx, &changes, "GET", "/accounts/", urlValues{
		"q": {q},
		"n": condInt(opt.N),
		"o": opt.Fields,
		"S": condInt(opt.Start),
	})
	return changes, err
}

// GetProjects returns a map of all projects on the Gerrit server.
func (c *Client) GetProjects(ctx context.Context, branch string) (map[string]*ProjectInfo, error) {
	mp := make(map[string]*ProjectInfo)
	err := c.do(ctx, &mp, "GET", fmt.Sprintf("/projects/?b=%s&format=JSON", branch))
	return mp, err
}

type TimeStamp time.Time

func (ts TimeStamp) Equal(v TimeStamp) bool {
	return ts.Time().Equal(v.Time())
}

// Gerrit's timestamp layout is like time.RFC3339Nano, but with a space instead of the "T",
// and without a timezone (it's always in UTC).
const timeStampLayout = "2006-01-02 15:04:05.999999999"

func (ts TimeStamp) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf(`"%s"`, ts.Time().UTC().Format(timeStampLayout))), nil
}

func (ts *TimeStamp) UnmarshalJSON(p []byte) error {
	if len(p) < 2 {
		return errors.New("Timestamp too short")
	}
	if p[0] != '"' || p[len(p)-1] != '"' {
		return errors.New("not double-quoted")
	}
	s := strings.Trim(string(p), "\"")
	t, err := time.Parse(timeStampLayout, s)
	if err != nil {
		return err
	}
	*ts = TimeStamp(t)
	return nil
}

func (ts TimeStamp) Time() time.Time { return time.Time(ts) }

// GroupInfo contains information about a group.
//
// See https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#group-info.
type GroupInfo struct {
	ID      string           `json:"id"`
	URL     string           `json:"url"`
	Name    string           `json:"name"`
	GroupID int64            `json:"group_id"`
	Options GroupOptionsInfo `json:"options"`
	Owner   string           `json:"owner"`
	OwnerID string           `json:"owner_id"`
}

type GroupOptionsInfo struct {
	VisibleToAll bool `json:"visible_to_all"`
}

func (c *Client) GetGroups(ctx context.Context) (map[string]*GroupInfo, error) {
	res := make(map[string]*GroupInfo)
	err := c.do(ctx, &res, "GET", "/groups/")
	for k, gi := range res {
		if gi != nil && gi.Name == "" {
			gi.Name = k
		}
	}
	return res, err
}

func (c *Client) GetGroupMembers(ctx context.Context, groupID string) ([]AccountInfo, error) {
	var ais []AccountInfo
	err := c.do(ctx, &ais, "GET", "/groups/"+groupID+"/members")
	return ais, err
}
