// Copyright 2017 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gerrit

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/retry"
	"go.chromium.org/luci/common/retry/transient"

	"golang.org/x/net/context/ctxhttp"
)

const contentType = "application/json; charset=UTF-8"

// Change represents a Gerrit CL. Information about these fields in:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-info
//
// Note that not all fields will be filled for all CLs and queries depending on
// query options, and not all fields exposed by Gerrit are captured by this
// struct. Adding more fields to this struct should be okay (but only
// Gerrit-supported keys will be populated).
//
// TODO(nodir): replace this type with
// https://godoc.org/go.chromium.org/luci/common/proto/gerrit#ChangeInfo.
type Change struct {
	ChangeNumber           int                     `json:"_number"`
	ID                     string                  `json:"id"`
	ChangeID               string                  `json:"change_id"`
	Project                string                  `json:"project"`
	Branch                 string                  `json:"branch"`
	Topic                  string                  `json:"topic"`
	Hashtags               []string                `json:"hashtags"`
	Subject                string                  `json:"subject"`
	Status                 string                  `json:"status"`
	Created                string                  `json:"created"`
	Updated                string                  `json:"updated"`
	Mergeable              bool                    `json:"mergeable,omitempty"`
	Messages               []ChangeMessageInfo     `json:"messages"`
	Submittable            bool                    `json:"submittable,omitempty"`
	Submitted              string                  `json:"submitted"`
	SubmitType             string                  `json:"submit_type"`
	Insertions             int                     `json:"insertions"`
	Deletions              int                     `json:"deletions"`
	UnresolvedCommentCount int                     `json:"unresolved_comment_count"`
	HasReviewStarted       bool                    `json:"has_review_started"`
	Owner                  AccountInfo             `json:"owner"`
	Labels                 map[string]LabelInfo    `json:"labels"`
	Submitter              AccountInfo             `json:"submitter"`
	Reviewers              Reviewers               `json:"reviewers"`
	RevertOf               int                     `json:"revert_of"`
	CurrentRevision        string                  `json:"current_revision"`
	WorkInProgress         bool                    `json:"work_in_progress,omitempty"`
	CherryPickOfChange     int                     `json:"cherry_pick_of_change"`
	CherryPickOfPatchset   int                     `json:"cherry_pick_of_patch_set"`
	Revisions              map[string]RevisionInfo `json:"revisions"`
	// MoreChanges is not part of a Change, but gerrit piggy-backs on the
	// last Change in a page to set this flag if there are more changes
	// in the results of a query.
	MoreChanges bool `json:"_more_changes"`
}

// ChangeMessageInfo contains information about a message attached to a change:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-message-info
type ChangeMessageInfo struct {
	ID         string      `json:"id"`
	Author     AccountInfo `json:"author,omitempty"`
	RealAuthor AccountInfo `json:"real_author,omitempty"`
	Date       Timestamp   `json:"date"`
	Message    string      `json:"message"`
	Tag        string      `json:"tag,omitempty"`
}

// LabelInfo contains information about a label on a change, always
// corresponding to the current patch set.
//
// Only one of Approved, Rejected, Recommended, and Disliked will be set, with
// priority Rejected > Approved > Recommended > Disliked if multiple users have
// given the label different values.
//
// TODO(mknyszek): Support 'value' and 'default_value' fields, as well as the
// fields given with the query parameter DETAILED_LABELS.
type LabelInfo struct {
	// Optional reflects whether the label is optional (neither necessary
	// for nor blocking submission).
	Optional bool `json:"optional,omitempty"`

	// Approved refers to one user who approved this label (max value).
	Approved *AccountInfo `json:"approved,omitempty"`

	// Rejected refers to one user who rejected this label (min value).
	Rejected *AccountInfo `json:"rejected,omitempty"`

	// Recommended refers to one user who recommended this label (positive
	// value, but not max).
	Recommended *AccountInfo `json:"recommended,omitempty"`

	// Disliked refers to one user who disliked this label (negative value
	// but not min).
	Disliked *AccountInfo `json:"disliked,omitempty"`

	// Blocking reflects whether this label block the submit operation.
	Blocking bool `json:"blocking,omitempty"`

	All    []VoteInfo        `json:"all,omitempty"`
	Values map[string]string `json:"values,omitempty"`
}

// RevisionKind represents the "kind" field for a patch set.
type RevisionKind string

// Known revision kinds.
var (
	RevisionRework                 RevisionKind = "REWORK"
	RevisionTrivialRebase                       = "TRIVIAL_REBASE"
	RevisionMergeFirstParentUpdate              = "MERGE_FIRST_PARENT_UPDATE"
	RevisionNoCodeChange                        = "NO_CODE_CHANGE"
	RevisionNoChange                            = "NO_CHANGE"
)

// RevisionInfo contains information about a specific patch set.
//
// Corresponds with
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#revision-info.
// TODO(mknyszek): Support the rest of that structure.
type RevisionInfo struct {
	// PatchSetNumber is the number associated with the given patch set.
	PatchSetNumber int `json:"_number"`

	// Kind is the kind of revision this is.
	//
	// Allowed values are specified in the RevisionKind type.
	Kind RevisionKind `json:"kind"`

	// Ref is the Git reference for the patchset.
	Ref string `json:"ref"`

	// Uploader represents the account which uploaded this patch set.
	Uploader AccountInfo `json:"uploader"`

	// The description of this patchset, as displayed in the patchset selector menu.
	Description string `json:"description,omitempty"`

	// The commit associated with this revision.
	Commit CommitInfo `json:"commit,omitempty"`

	// A map of modified file paths to FileInfos.
	Files map[string]FileInfo `json:"files,omitempty"`
}

// CommitInfo contains information about a commit.
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#commit-info
//
// TODO(kjharland): Support remaining fields.
type CommitInfo struct {
	Commit    string       `json:"commit,omitempty"`
	Parents   []CommitInfo `json:"parents,omitempty"`
	Author    AccountInfo  `json:"author,omitempty"`
	Committer AccountInfo  `json:"committer,omitempty"`
	Subject   string       `json:"subject,omitempty"`
	Message   string       `json:"message,omitempty"`
}

// FileInfo contains information about a file in a patch set.
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#file-info
type FileInfo struct {
	Status        string `json:"status,omitempty"`
	Binary        bool   `json:"binary,omitempty"`
	OldPath       string `json:"old_path,omitempty"`
	LinesInserted int    `json:"lines_inserted,omitempty"`
	LinesDeleted  int    `json:"lines_deleted,omitempty"`
	SizeDelta     int64  `json:"size_delta"`
	Size          int64  `json:"size"`
}

// Reviewers is a map that maps a type of reviewer to its account info.
type Reviewers struct {
	CC       []AccountInfo `json:"CC"`
	Reviewer []AccountInfo `json:"REVIEWER"`
	Removed  []AccountInfo `json:"REMOVED"`
}

// AccountInfo contains information about an account.
type AccountInfo struct {
	// AccountID is the numeric ID of the account managed by Gerrit, and is guaranteed to
	// be unique.
	AccountID int `json:"_account_id,omitempty"`

	// Name is the full name of the user.
	Name string `json:"name,omitempty"`

	// Email is the email address the user prefers to be contacted through.
	Email string `json:"email,omitempty"`

	// SecondaryEmails is a list of secondary email addresses of the user.
	SecondaryEmails []string `json:"secondary_emails,omitempty"`

	// Username is the username of the user.
	Username string `json:"username,omitempty"`

	// MoreAccounts represents whether the query would deliver more results if not limited.
	// Only set on the last account that is returned.
	MoreAccounts bool `json:"_more_accounts,omitempty"`
}

// VoteInfo is AccountInfo plus a value field, used to represent votes on a label.
type VoteInfo struct {
	AccountInfo       // Embedded type
	Value       int64 `json:"value"`
}

// SubmittedTogetherInfo contains information about a collection of changes that would be submitted together.
type SubmittedTogetherInfo struct {

	// A list of ChangeInfo entities representing the changes to be submitted together.
	Changes []Change `json:"changes"`

	// The number of changes to be submitted together that the current user cannot see.
	NonVisibleChanges int `json:"non_visible_changes,omitempty"`
}

// BranchInfo contains information about a branch.
type BranchInfo struct {
	// Ref is the ref of the branch.
	Ref string `json:"ref"`

	// Revision is the revision to which the branch points.
	Revision string `json:"revision"`
}

// ValidateGerritURL validates Gerrit URL for use in this package.
func ValidateGerritURL(gerritURL string) error {
	_, err := NormalizeGerritURL(gerritURL)
	return err
}

// NormalizeGerritURL returns canonical for Gerrit URL.
//
// error is returned if validation fails.
func NormalizeGerritURL(gerritURL string) (string, error) {
	u, err := url.Parse(gerritURL)
	if err != nil {
		return "", err
	}
	if u.Scheme != "https" {
		return "", fmt.Errorf("%s should start with https://", gerritURL)
	}
	if !strings.HasSuffix(u.Host, "-review.googlesource.com") {
		return "", errors.New("only *-review.googlesource.com Gerrits supported")
	}
	if u.Fragment != "" {
		return "", errors.New("no fragments allowed in gerritURL")
	}
	if u.Path != "" && u.Path != "/" {
		return "", errors.New("Unexpected path in URL")
	}
	if u.Path != "/" {
		u.Path = "/"
	}
	return u.String(), nil
}

// Client is a production Gerrit client, instantiated via NewClient(),
// and uses an http.Client along with a validated url to communicate with
// Gerrit.
type Client struct {
	httpClient *http.Client

	// Set by NewClient after validation.
	gerritURL url.URL

	// Strategy for retrying GET requests. Other requests are not retried as
	// they may not be idempotent.
	retryStrategy retry.Factory
}

// NewClient creates a new instance of Client and validates and stores
// the URL to reach Gerrit. The result is wrapped inside a Client so that
// the apis can be called directly on the value returned by this function.
func NewClient(c *http.Client, gerritURL string) (*Client, error) {
	u, err := NormalizeGerritURL(gerritURL)
	if err != nil {
		return nil, err
	}
	pu, err := url.Parse(u)
	if err != nil {
		return nil, err
	}
	return &Client{c, *pu, retry.Default}, nil
}

// EmailInfo contains the response fields from ListAccountEmails.
type EmailInfo struct {
	// Email address linked to the user account.
	Email string `json:"email"`

	// Set true if the email address is set as preferred.
	Preferred bool `json:"preferred"`

	// Set true if the user must confirm control of the email address by following
	// a verification link before Gerrit will permit use of this address.
	PendingConfirmation bool `json:"pending_confirmation"`
}

// ListAccountEmails returns the email addresses linked in the given Gerrit account.
func (c *Client) ListAccountEmails(email string) ([]*EmailInfo, error) {
	panic("not implemented")
}

// ChangeQueryParams contains the parameters necessary for querying changes from Gerrit.
type ChangeQueryParams struct {
	// Actual query string, see
	// https://gerrit-review.googlesource.com/Documentation/user-search.html#_search_operators
	Query string `json:"q"`
	// How many changes to include in the response.
	N int `json:"n"`
	// Skip this many from the list of results (unreliable for paging).
	S int `json:"S"`
	// Include these options in the queries. Certain options will make
	// Gerrit fill in additional fields of the response. These require
	// additional database searches and may delay the response.
	//
	// The supported strings for options are listed in Gerrit's api
	// documentation at the link below:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
	Options []string `json:"o"`
}

// queryString renders the ChangeQueryParams as a url.Values.
func (qr *ChangeQueryParams) queryString() url.Values {
	qs := make(url.Values, len(qr.Options)+3)
	qs.Add("q", qr.Query)
	if qr.N > 0 {
		qs.Add("n", strconv.Itoa(qr.N))
	}
	if qr.S > 0 {
		qs.Add("S", strconv.Itoa(qr.S))
	}
	for _, o := range qr.Options {
		qs.Add("o", o)
	}
	return qs
}

// ChangeQuery returns a list of Gerrit changes for a given ChangeQueryParams.
//
// One example use case for this is getting the CL for a given commit hash.
// Only the .Query property of the qr parameter is required.
//
// Returns a slice of Change, whether there are more changes to fetch
// and an error.
func (c *Client) ChangeQuery(ctx context.Context, qr ChangeQueryParams) ([]*Change, bool, error) {
	var resp struct {
		Collection []*Change
	}
	if _, err := c.get(ctx, "a/changes/", qr.queryString(), &resp.Collection); err != nil {
		return nil, false, err
	}
	result := resp.Collection
	moreChanges := false
	if len(result) > 0 {
		moreChanges = result[len(result)-1].MoreChanges
		result[len(result)-1].MoreChanges = false
	}
	return result, moreChanges, nil
}

// ChangeDetailsParams contains optional parameters for getting change details from Gerrit.
type ChangeDetailsParams struct {
	// Options is a set of optional details to add as additional fieldsof the response.
	// These require additional database searches and may delay the response.
	//
	// The supported strings for options are listed in Gerrit's api
	// documentation at the link below:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
	Options []string `json:"o"`
}

// queryString renders the ChangeDetailsParams as a url.Values.
func (qr *ChangeDetailsParams) queryString() url.Values {
	qs := make(url.Values, len(qr.Options))
	for _, o := range qr.Options {
		qs.Add("o", o)
	}
	return qs
}

// ChangeDetails gets details about a single change with optional fields.
//
// This method returns a single *Change and an error.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
//
// options is a list of strings like {"CURRENT_REVISION"} which tells Gerrit
// to return non-default properties for Change. The supported strings for
// options are listed in Gerrit's api documentation at the link below:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
func (c *Client) ChangeDetails(ctx context.Context, changeID string, options ChangeDetailsParams) (*Change, error) {
	var resp Change
	path := fmt.Sprintf("a/changes/%s/detail", url.PathEscape(changeID))
	if _, err := c.get(ctx, path, options.queryString(), &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// The CommentInput entity contains information for creating an inline comment.
type CommentInput struct {
	// The URL encoded UUID of the comment if an existing draft comment should be updated.
	// Optional
	ID string `json:"id,omitempty"`

	// The file path for which the inline comment should be added.
	// Doesn’t need to be set if contained in a map where the key is the file path.
	// Optional
	Path string `json:"path,omitempty"`

	// The side on which the comment should be added.
	// Allowed values are REVISION and PARENT.
	// If not set, the default is REVISION.
	// Optional
	Side string `json:"side,omitempty"`

	// The number of the line for which the comment should be added.
	// 0 if it is a file comment.
	// If neither line nor range is set, a file comment is added.
	// If range is set, this value is ignored in favor of the end_line of the range.
	// Optional
	Line int `json:"line,omitempty"`

	// The range of the comment as a CommentRange entity.
	// Optional
	Range CommentRange `json:"range,omitempty"`

	// The URL encoded UUID of the comment to which this comment is a reply.
	// Optional
	InReplyTo string `json:"in_reply_to,omitempty"`

	// The comment message.
	// If not set and an existing draft comment is updated, the existing draft comment is deleted.
	// Optional
	Message string `json:"message,omitempty"`

	// Value of the tag field. Only allowed on draft comment inputs;
	// for published comments, use the tag field in ReviewInput.
	// Votes/comments that contain tag with 'autogenerated:' prefix can be filtered out in the web UI.
	// Optional
	Tag string `json:"tag,omitempty"`

	// Whether or not the comment must be addressed by the user.
	// This value will default to false if the comment is an orphan, or the
	// value of the in_reply_to comment if it is supplied.
	// Optional
	Unresolved bool `json:"unresolved,omitempty"`
}

// The RobotCommentInput entity contains information for creating an inline
// robot comment.
type RobotCommentInput struct {
	// The name of the robot that generated this comment.
	// Required
	RobotID string `json:"robot_id"`

	// A unique ID of the run of the robot.
	// Required
	RobotRunID string `json:"robot_run_id"`

	// The file path for which the inline comment should be added.
	Path string `json:"path,omitempty"`

	// The side on which the comment should be added.
	// Allowed values are REVISION and PARENT.
	// If not set, the default is REVISION.
	// Optional
	Side string `json:"side,omitempty"`

	// The number of the line for which the comment should be added.
	// 0 if it is a file comment.
	// If neither line nor range is set, a file comment is added.
	// If range is set, this value is ignored in favor of the end_line of the range.
	// Optional
	Line int `json:"line,omitempty"`

	// The range of the comment as a CommentRange entity.
	// Optional
	Range *CommentRange `json:"range,omitempty"`

	// The URL encoded UUID of the comment to which this comment is a reply.
	// Optional
	InReplyTo string `json:"in_reply_to,omitempty"`

	// The comment message.
	// If not set and an existing draft comment is updated, the existing draft comment is deleted.
	// Optional
	Message string `json:"message,omitempty"`

	// Suggested fixes.
	FixSuggestions []FixSuggestion `json:"fix_suggestions,omitempty"`
}

// FixSuggestion represents a suggested fix for a robot comment.
type FixSuggestion struct {
	Description  string        `json:"description"`
	Replacements []Replacement `json:"replacements"`
}

// Replacement represents a potential source replacement for applying a
// suggested fix.
type Replacement struct {
	Path        string        `json:"path"`
	Replacement string        `json:"replacement"`
	Range       *CommentRange `json:"range,omitempty"`
}

// CommentRange is included within Comment. See Comment for more details.
type CommentRange struct {
	StartLine      int `json:"start_line,omitempty"`
	StartCharacter int `json:"start_character,omitempty"`
	EndLine        int `json:"end_line,omitempty"`
	EndCharacter   int `json:"end_character,omitempty"`
}

// Comment represents a comment on a Gerrit CL. Information about these fields
// is in:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-info
//
// Note that not all fields will be filled for all comments depending on the
// way the comment was added to Gerrit, and not all fields exposed by Gerrit
// are captured by this struct. Adding more fields to this struct should be
// okay (but only Gerrit-supported keys will be populated).
type Comment struct {
	ID              string       `json:"id"`
	Owner           AccountInfo  `json:"author"`
	ChangeMessageID string       `json:"change_message_id"`
	PatchSet        int          `json:"patch_set"`
	Line            int          `json:"line"`
	Range           CommentRange `json:"range"`
	Updated         string       `json:"updated"`
	Message         string       `json:"message"`
	Unresolved      bool         `json:"unresolved"`
	InReplyTo       string       `json:"in_reply_to"`
	CommitID        string       `json:"commit_id"`
}

// RobotComment represents a robot comment on a Gerrit CL. Information about
// these fields is in:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#robot-comment-info
//
// RobotComment shares most of the same fields with Comment. Note that robot
// comments do not have the `unresolved` field so it will always be false.
type RobotComment struct {
	Comment

	RobotID    string            `json:"robot_id"`
	RobotRunID string            `json:"robot_run_id"`
	URL        string            `json:"url"`
	Properties map[string]string `json:"properties"`
}

// ListChangeComments gets all comments on a single change.
//
// This method returns a list of comments for each file path (including
// pseudo-files like '/PATCHSET_LEVEL' and '/COMMIT_MSG') and an error.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) ListChangeComments(ctx context.Context, changeID string, revisionID string) (map[string][]Comment, error) {
	var resp map[string][]Comment
	var path string
	if revisionID != "" {
		path = fmt.Sprintf("a/changes/%s/revisions/%s/comments", url.PathEscape(changeID), url.PathEscape(revisionID))
	} else {
		path = fmt.Sprintf("a/changes/%s/comments", url.PathEscape(changeID))
	}
	if _, err := c.get(ctx, path, url.Values{}, &resp); err != nil {
		return nil, err
	}
	return resp, nil
}

// ListRobotComments gets all robot comments on a single change.
//
// This method returns a list of robot comments for each file path (including
// pseudo-files like '/PATCHSET_LEVEL' and '/COMMIT_MSG') and an error.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) ListRobotComments(ctx context.Context, changeID string, revisionID string) (map[string][]RobotComment, error) {
	var resp map[string][]RobotComment
	var path string
	if revisionID != "" {
		path = fmt.Sprintf("a/changes/%s/revisions/%s/robotcomments", url.PathEscape(changeID), url.PathEscape(revisionID))
	} else {
		path = fmt.Sprintf("a/changes/%s/robotcomments", url.PathEscape(changeID))
	}
	if _, err := c.get(ctx, path, url.Values{}, &resp); err != nil {
		return nil, err
	}
	return resp, nil
}

// ChangesSubmittedTogether returns a list of Gerrit changes which are submitted
// when Submit is called for the given change, including the current change itself.
// As a special case, the list is empty if this change would be submitted by itself
// (without other changes).
//
// Returns a slice of Change and an error.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#submitted-together
//
// options is a list of strings like {"CURRENT_REVISION"} which tells Gerrit
// to return non-default properties for each Change. The supported strings for
// options are listed in Gerrit's api documentation at the link below:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
func (c *Client) ChangesSubmittedTogether(ctx context.Context, changeID string, options ChangeDetailsParams) (*SubmittedTogetherInfo, error) {
	var resp SubmittedTogetherInfo
	path := fmt.Sprintf("a/changes/%s/submitted_together", url.PathEscape(changeID))
	if _, err := c.get(ctx, path, options.queryString(), &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ChangeInput contains the parameters necessary for creating a change in
// Gerrit.
//
// This struct is intended to be one-to-one with the ChangeInput structure
// described in Gerrit's documentation:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-input
//
// The exception is only status, which is always "NEW" and is therefore unavailable in
// this struct.
//
// TODO(mknyszek): Support merge and notify_details.
type ChangeInput struct {
	// Project is the name of the project for this change.
	Project string `json:"project"`

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

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

	// Topic is the topic to which this change belongs. Optional.
	Topic string `json:"topic,omitempty"`

	// IsPrivate sets whether the change is marked private.
	IsPrivate bool `json:"is_private,omitempty"`

	// WorkInProgress sets the work-in-progress bit for the change.
	WorkInProgress bool `json:"work_in_progress,omitempty"`

	// BaseChange is the change this new change is based on. Optional.
	//
	// This can be anything Gerrit expects as a ChangeID. We recommend <numericId>,
	// but the full list of supported formats can be found here:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
	BaseChange string `json:"base_change,omitempty"`

	// NewBranch allows for creating a new branch when set to true.
	NewBranch bool `json:"new_branch,omitempty"`

	// Notify is an enum specifying whom to send notifications to.
	//
	// Valid values are NONE, OWNER, OWNER_REVIEWERS, and ALL.
	//
	// Optional. The default is ALL.
	Notify string `json:"notify,omitempty"`
}

// CreateChange creates a new change in Gerrit.
//
// Returns a Change describing the newly created change or an error.
func (c *Client) CreateChange(ctx context.Context, ci *ChangeInput) (*Change, error) {
	var resp Change
	if _, err := c.post(ctx, "a/changes/", ci, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// AbandonInput contains information for abandoning a change.
//
// This struct is intended to be one-to-one with the AbandonInput structure
// described in Gerrit's documentation:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#abandon-input
//
// TODO(mknyszek): Support notify_details.
type AbandonInput struct {
	// Message to be added as review comment to the change when abandoning it.
	Message string `json:"message,omitempty"`

	// Notify is an enum specifying whom to send notifications to.
	//
	// Valid values are NONE, OWNER, OWNER_REVIEWERS, and ALL.
	//
	// Optional. The default is ALL.
	Notify string `json:"notify,omitempty"`
}

// AbandonChange abandons an existing change in Gerrit.
//
// Returns a Change referenced by changeID, with status ABANDONED, if
// abandoned.
//
// AbandonInput is optional (that is, may be nil).
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) AbandonChange(ctx context.Context, changeID string, ai *AbandonInput) (*Change, error) {
	var resp Change
	path := fmt.Sprintf("a/changes/%s/abandon", url.PathEscape(changeID))
	if _, err := c.post(ctx, path, ai, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// IsChangePureRevert determines if a change is a pure revert of another commit.
//
// This method returns a bool and an error.
//
// To determine which commit the change is purportedly reverting, use the
// revert_of property of the change.
//
// Gerrit's doc for the api:
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-pure-revert
func (c *Client) IsChangePureRevert(ctx context.Context, changeID string) (bool, error) {
	resp := &pureRevertResponse{}
	path := fmt.Sprintf("changes/%s/pure_revert", url.PathEscape(changeID))
	sc, err := c.get(ctx, path, url.Values{}, resp)
	if err != nil {
		switch sc {
		case 400:
			return false, nil
		default:
			return false, err
		}
	}
	return resp.IsPureRevert, nil
}

// ReviewerInput contains information for adding a reviewer to a change.
//
// TODO(mknyszek): Add support for notify_details.
type ReviewerInput struct {
	// Reviewer is an account-id that should be added as a reviewer, or a group-id for which
	// all members should be added as reviewers. If Reviewer identifies both an account and a
	// group, only the account is added as a reviewer to the change.
	//
	// More information on account-id may be found here:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-id
	//
	// More information on group-id may be found here:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#group-id
	Reviewer string `json:"reviewer"`

	// State is the state in which to add the reviewer. Possible reviewer states are REVIEWER
	// and CC. If not given, defaults to REVIEWER.
	State string `json:"state,omitempty"`

	// Confirmed represents whether adding the reviewer is confirmed.
	//
	// The Gerrit server may be configured to require a confirmation when adding a group as
	// a reviewer that has many members.
	Confirmed bool `json:"confirmed"`

	// Notify is an enum specifying whom to send notifications to.
	//
	// Valid values are NONE, OWNER, OWNER_REVIEWERS, and ALL.
	//
	// Optional. The default is ALL.
	Notify string `json:"notify,omitempty"`
}

// ReviewInput contains information for adding a review to a revision.
//
// TODO(mknyszek): Add support for drafts, notify, and omit_duplicate_comments.
type ReviewInput struct {
	// Inline comments to be added to the revision.
	Comments map[string][]CommentInput `json:"comments,omitempty"`

	// Robot comments to be added to the revision.
	RobotComments map[string][]RobotCommentInput `json:"robot_comments,omitempty"`

	// Message is the message to be added as a review comment.
	Message string `json:"message,omitempty"`

	// Tag represents a tag to apply to review comment messages, votes, and inline comments.
	//
	// Tags may be used by CI or other automated systems to distinguish them from human
	// reviews.
	Tag string `json:"tag,omitempty"`

	// Labels represents the votes that should be added to the revision as a map of label names
	// to voting values.
	Labels map[string]int `json:"labels,omitempty"`

	// Notify is an enum specifying whom to send notifications to.
	//
	// Valid values are NONE, OWNER, OWNER_REVIEWERS, and ALL.
	//
	// Optional. The default is ALL.
	Notify string `json:"notify,omitempty"`

	// OnBehalfOf is an account-id which the review should be posted on behalf of.
	//
	// To use this option the caller must have granted labelAs-NAME permission for all keys
	// of labels.
	//
	// More information on account-id may be found here:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-id
	OnBehalfOf string `json:"on_behalf_of,omitempty"`

	// Reviewers is a list of ReviewerInput representing reviewers that should be added to the change. Optional.
	Reviewers []ReviewerInput `json:"reviewers,omitempty"`

	// Ready, if set to true, will move the change from WIP to ready to review if possible.
	//
	// It is an error for both Ready and WorkInProgress to be true.
	Ready bool `json:"ready,omitempty"`

	// WorkInProgress sets the work-in-progress bit for the change.
	//
	// It is an error for both Ready and WorkInProgress to be true.
	WorkInProgress bool `json:"work_in_progress,omitempty"`
}

// SubmitInput contains information for submitting a change.
type SubmitInput struct {
	// Notify is an enum specifying whom to send notifications to.
	//
	// Valid values are NONE, OWNER, OWNER_REVIEWERS, and ALL.
	//
	// Optional. The default is ALL.
	Notify string `json:"notify,omitempty"`

	// OnBehalfOf is an account-id which the review should be posted on behalf of.
	//
	// To use this option the caller must have granted labelAs-NAME permission for all keys
	// of labels.
	//
	// More information on account-id may be found here:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-id
	OnBehalfOf string `json:"on_behalf_of,omitempty"`
}

// ReviewerInfo contains information about a reviewer and their votes on a change.
//
// It has the same fields as AccountInfo, except the AccountID is optional if an unregistered reviewer
// was added.
type ReviewerInfo struct {
	AccountInfo

	// Approvals maps label names to the approval values given by this reviewer.
	Approvals map[string]string `json:"approvals,omitempty"`
}

// AddReviewerResult describes the result of adding a reviewer to a change.
type AddReviewerResult struct {
	// Input is the value of the `reviewer` field from ReviewerInput set while adding the reviewer.
	Input string `json:"input"`

	// Reviewers is a list of newly added reviewers.
	Reviewers []ReviewerInfo `json:"reviewers,omitempty"`

	// CCs is a list of newly CCed accounts. This field will only appear if the requested `state`
	// for the reviewer was CC and NoteDb is enabled on the server.
	CCs []ReviewerInfo `json:"ccs,omitempty"`

	// Error is a message explaining why the reviewer could not be added.
	//
	// If a group was specified in the input and an error is returned, that means none of the
	// members were added as reviewer.
	Error string `json:"error,omitempty"`

	// Confirm represents whether adding the reviewer requires confirmation.
	Confirm bool `json:"confirm,omitempty"`
}

// ReviewResult contains information regarding the updates that were made to a review.
type ReviewResult struct {
	// Labels is a map of labels to values after the review was posted.
	//
	// nil if any reviewer additions were rejected.
	Labels map[string]int `json:"labels,omitempty"`

	// Reviewers is a map of accounts or group identifiers to an AddReviewerResult representing
	// the outcome of adding the reviewer.
	//
	// Absent if no reviewer additions were requested.
	Reviewers map[string]AddReviewerResult `json:"reviewers,omitempty"`

	// Ready marks if the change was moved from WIP to ready for review as a result of this action.
	Ready bool `json:"ready,omitempty"`
}

// SetReview sets a review on a revision, optionally also publishing
// draft comments, setting labels, adding reviewers or CCs, and modifying
// the work in progress property.
//
// Returns a ReviewResult which describes the applied labels and any added reviewers.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
//
// The revisionID parameter may be in any of the forms supported by Gerrit:
//   - "current"
//   - a commit ID
//   - "0" or the literal "edit" for a change edit
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#revision-id
func (c *Client) SetReview(ctx context.Context, changeID string, revisionID string, ri *ReviewInput) (*ReviewResult, error) {
	var resp ReviewResult
	path := fmt.Sprintf("a/changes/%s/revisions/%s/review", url.PathEscape(changeID), url.PathEscape(revisionID))
	if _, err := c.post(ctx, path, ri, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// MergeableResult contains information if the change for the revision can be merged or not.
type MergeableResult struct {

	// Mergeable marks if the change is ready to be submitted cleanly, false otherwise
	Mergeable bool `json:"mergeable"`
}

// GetMergeable API checks if a change is ready to be submitted cleanly.
//
// Returns a MergeableResult that has details if the change be merged or not.
func (c *Client) GetMergeable(ctx context.Context, changeID string, revisionID string) (*MergeableResult, error) {
	var resp MergeableResult
	path := fmt.Sprintf("a/changes/%s/revisions/%s/mergeable", url.PathEscape(changeID), url.PathEscape(revisionID))
	if _, err := c.get(ctx, path, url.Values{}, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// Submit submits a change to the repository. It bypasses the Commit Queue.
//
// Returns a Change.
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) Submit(ctx context.Context, changeID string, si *SubmitInput) (*Change, error) {
	var resp Change
	path := fmt.Sprintf("a/changes/%s/submit", url.PathEscape(changeID))
	if _, err := c.post(ctx, path, si, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// RebaseInput contains information for rebasing a change.
type RebaseInput struct {
	// Base is the revision to rebase on top of.
	Base string `json:"base,omitempty"`

	// AllowConflicts allows the rebase to succeed even if there are conflicts.
	AllowConflicts bool `json:"allow_conflicts,omitempty"`

	// OnBehalfOfUploader causes the rebase to be done on behalf of the
	// uploader. This means the uploader of the current patch set will also be
	// the uploader of the rebased patch set.
	//
	// Rebasing on behalf of the uploader is only supported for trivial rebases.
	// This means this option cannot be combined with the `allow_conflicts`
	// option.
	OnBehalfOfUploader bool `json:"on_behalf_of_uploader,omitempty"`
}

// RebaseChange rebases an open change on top of a specified revision (or its
// parent change, if no revision is specified).
//
// Returns a Change referenced by changeID, if rebased.
//
// RebaseInput is optional (that is, may be nil).
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) RebaseChange(ctx context.Context, changeID string, ri *RebaseInput) (*Change, error) {
	var resp Change
	path := fmt.Sprintf("a/changes/%s/rebase", url.PathEscape(changeID))
	if _, err := c.post(ctx, path, ri, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// RestoreInput contains information for restoring a change.
type RestoreInput struct {
	// Message is the message to be added as review comment to the change when restoring the change.
	Message string `json:"message,omitempty"`
}

// RestoreChange restores an existing abandoned change in Gerrit.
//
// Returns a Change referenced by changeID, if restored.
//
// RestoreInput is optional (that is, may be nil).
//
// The changeID parameter may be in any of the forms supported by Gerrit:
//   - "4247"
//   - "I8473b95934b5732ac55d26311a706c9c2bde9940"
//   - etc. See the link below.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
func (c *Client) RestoreChange(ctx context.Context, changeID string, ri *RestoreInput) (*Change, error) {
	var resp Change
	path := fmt.Sprintf("a/changes/%s/restore", url.PathEscape(changeID))
	if _, err := c.post(ctx, path, ri, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// BranchInput contains information for creating a branch.
type BranchInput struct {
	// Ref is the name of the branch.
	Ref string `json:"ref,omitempty"`

	// Revision is the base revision of the new branch.
	Revision string `json:"revision,omitempty"`
}

// CreateBranch creates a branch.
//
// Returns BranchInfo, or an error if the branch could not be created.
//
// See the link below for API documentation.
// https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#create-branch
func (c *Client) CreateBranch(ctx context.Context, projectID string, bi *BranchInput) (*BranchInfo, error) {
	var resp BranchInfo
	path := fmt.Sprintf("a/projects/%s/branches/%s", url.PathEscape(projectID), url.PathEscape(bi.Ref))
	if _, err := c.post(ctx, path, bi, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// AccountQueryParams contains the parameters necessary for querying accounts from Gerrit.
type AccountQueryParams struct {
	// Actual query string, see
	// https://gerrit-review.googlesource.com/Documentation/user-search-accounts.html#_search_operators
	Query string `json:"q"`
	// How many changes to include in the response.
	N int `json:"n"`
	// Skip this many from the list of results (unreliable for paging).
	S int `json:"S"`
	// Include these options in the queries. Certain options will make
	// Gerrit fill in additional fields of the response. These require
	// additional database searches and may delay the response.
	//
	// The supported strings for options are listed in Gerrit's api
	// documentation at the link below:
	// https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html
	Options []string `json:"o"`
}

// queryString renders the ChangeQueryParams as a url.Values.
func (qr *AccountQueryParams) queryString() url.Values {
	qs := make(url.Values, len(qr.Options)+3)
	qs.Add("q", qr.Query)
	if qr.N > 0 {
		qs.Add("n", strconv.Itoa(qr.N))
	}
	if qr.S > 0 {
		qs.Add("S", strconv.Itoa(qr.S))
	}
	for _, o := range qr.Options {
		qs.Add("o", o)
	}
	return qs
}

// AccountQuery gets all matching accounts.
//
// Only the .Query property of the qr parameter is required.
//
// Returns a slice of AccountInfo, whether there are more accounts to fetch,
// and an error.
//
// https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html
func (c *Client) AccountQuery(ctx context.Context, qr AccountQueryParams) ([]*AccountInfo, bool, error) {
	var resp struct{ Collection []*AccountInfo }
	if _, err := c.get(ctx, "a/accounts/", qr.queryString(), &resp.Collection); err != nil {
		return nil, false, err
	}
	result := resp.Collection
	moreAccounts := false
	if len(result) > 0 {
		moreAccounts = result[len(result)-1].MoreAccounts
		result[len(result)-1].MoreAccounts = false
	}
	return result, moreAccounts, nil
}

func (c *Client) get(ctx context.Context, path string, query url.Values, result any) (int, error) {
	u := c.gerritURL
	u.Opaque = "//" + u.Host + "/" + path
	u.RawQuery = query.Encode()

	var statusCode int
	err := retry.Retry(ctx, transient.Only(c.retryStrategy), func() error {
		var err error
		statusCode, err = c.getOnce(ctx, u, result)
		return err
	}, nil)
	return statusCode, err
}

func (c *Client) getOnce(ctx context.Context, u url.URL, result any) (int, error) {
	r, err := ctxhttp.Get(ctx, c.httpClient, u.String())
	if err != nil {
		return 0, transient.Tag.Apply(err)
	}
	defer r.Body.Close()
	if r.StatusCode < 200 || r.StatusCode >= 300 {
		err = errors.Reason("failed to fetch %q, status code %d", u.String(), r.StatusCode).Err()
		if r.StatusCode >= 500 {
			err = transient.Tag.Apply(err)
		}
		return r.StatusCode, err
	}
	return r.StatusCode, parseResponse(r.Body, result)
}

func (c *Client) post(ctx context.Context, path string, data any, result any) (int, error) {
	var buffer bytes.Buffer
	if err := json.NewEncoder(&buffer).Encode(data); err != nil {
		return 200, err
	}
	u := c.gerritURL
	u.Opaque = "//" + u.Host + "/" + path
	r, err := ctxhttp.Post(ctx, c.httpClient, u.String(), contentType, &buffer)
	if err != nil {
		return 0, transient.Tag.Apply(err)
	}
	defer r.Body.Close()
	if r.StatusCode < 200 || r.StatusCode >= 300 {
		b, err := io.ReadAll(r.Body)
		if err != nil {
			return 0, transient.Tag.Apply(err)
		}
		err = errors.Reason("failed to post to %q, status code %d: %s", u.String(), r.StatusCode, strings.TrimSpace(string(b))).Err()
		if r.StatusCode >= 500 {
			err = transient.Tag.Apply(err)
		}
		return r.StatusCode, err
	}
	return r.StatusCode, parseResponse(r.Body, result)
}

func parseResponse(resp io.Reader, result any) error {
	// Strip out the jsonp header, which is ")]}'"
	const gerritPrefix = ")]}'"
	trash := make([]byte, len(gerritPrefix))
	cnt, err := resp.Read(trash)
	if err != nil {
		return errors.Annotate(err, "unexpected response from Gerrit").Err()
	}
	if cnt != len(gerritPrefix) || gerritPrefix != string(trash) {
		return errors.New("unexpected response from Gerrit")
	}
	if err = json.NewDecoder(resp).Decode(result); err != nil {
		return errors.Annotate(err, "failed to decode Gerrit response into %T", result).Err()
	}
	return nil
}

// pureRevertResponse contains the response fields for calls to get-pure-revert
// api.
type pureRevertResponse struct {
	IsPureRevert bool `json:"is_pure_revert"`
}
