// Copyright 2020 The Fuchsia 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 (
	"context"
	"fmt"

	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/common/api/gerrit"
	"go.chromium.org/luci/common/errors"
	gerritpb "go.chromium.org/luci/common/proto/gerrit"
	"go.chromium.org/luci/common/retry/transient"
)

const commitQueueLabel = "Commit-Queue"

// gerritClientWrapper provides utilities for interacting with a Gerrit project.
type gerritClientWrapper struct {
	client  gerritpb.GerritClient
	project string
}

// newGerritClient returns an authenticated gerritClientWrapper.
func newGerritClient(ctx context.Context, host, project string, authOpts auth.Options) (*gerritClientWrapper, error) {
	authClient, err := newAuthClient(ctx, authOpts)
	if err != nil {
		return nil, err
	}
	client, err := gerrit.NewRESTClient(authClient, host, true)
	if err != nil {
		return nil, err
	}
	return &gerritClientWrapper{client: client, project: project}, nil
}

// createChange creates an empty Gerrit change.
func (c *gerritClientWrapper) createChange(ctx context.Context, subject, baseCommit string) (*gerritpb.ChangeInfo, error) {
	return c.client.CreateChange(ctx, &gerritpb.CreateChangeRequest{
		Project:    c.project,
		Ref:        "refs/heads/master",
		Subject:    subject,
		BaseCommit: baseCommit,
	})
}

// editFile edits a single file for a Gerrit change.
func (c *gerritClientWrapper) editFile(ctx context.Context, changeNum int64, filepath, content string) error {
	_, err := c.client.ChangeEditFileContent(ctx, &gerritpb.ChangeEditFileContentRequest{
		Number:   changeNum,
		Project:  c.project,
		FilePath: filepath,
		Content:  []byte(content),
	})
	return err
}

// publishEdits publishes all pending edits on a Gerrit change.
func (c *gerritClientWrapper) publishEdits(ctx context.Context, changeNum int64) error {
	_, err := c.client.ChangeEditPublish(ctx, &gerritpb.ChangeEditPublishRequest{
		Number:  changeNum,
		Project: c.project,
	})
	return err
}

// setCQLabel sets the CQ+1/2 label on a Gerrit change.
func (c *gerritClientWrapper) setCQLabel(ctx context.Context, changeNum int64, dryRun bool) error {
	cqValue := int32(2)
	if dryRun {
		cqValue = int32(1)
	}
	changeRes, err := c.client.GetChange(ctx, &gerritpb.GetChangeRequest{
		Number:  changeNum,
		Options: []gerritpb.QueryOption{gerritpb.QueryOption_CURRENT_REVISION},
	})
	if err != nil {
		return err
	}
	reviewRes, err := c.client.SetReview(ctx, &gerritpb.SetReviewRequest{
		Number:     changeNum,
		Project:    c.project,
		RevisionId: changeRes.CurrentRevision,
		Labels:     map[string]int32{commitQueueLabel: cqValue},
	})
	if err != nil {
		return err
	}
	setValue, ok := reviewRes.Labels[commitQueueLabel]
	if !ok {
		return fmt.Errorf("%s label was rejected", commitQueueLabel)
	}
	if setValue != cqValue {
		return fmt.Errorf("%s label is %d; expected %d", commitQueueLabel, setValue, cqValue)
	}
	return nil
}

// checkCQCompletion checks if a Gerrit change's CQ label is unset.
func (c *gerritClientWrapper) checkCQCompletion(ctx context.Context, changeNum int64) error {
	changeInfo, err := c.client.GetChange(ctx, &gerritpb.GetChangeRequest{
		Number:  changeNum,
		Options: []gerritpb.QueryOption{gerritpb.QueryOption_LABELS},
	})
	if err != nil {
		return err
	}
	labelInfo, ok := changeInfo.Labels[commitQueueLabel]
	if !ok {
		return fmt.Errorf("%s label was not returned", commitQueueLabel)
	}
	// The CQ label will be unset eventually, so tag this error as transient.
	if labelInfo.Value != 0 {
		return errors.New(fmt.Sprintf("%s label is still set", commitQueueLabel), transient.Tag)
	}
	return nil
}
