// Package gerrit implements CodeReview for Gerrit.
package gerrit

import (
	"context"
	"path"
	"strconv"

	"go.skia.org/infra/docsyserver/go/codereview"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/go/gitiles"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/skerr"
)

// The commit message for a Gerrit CL shows up as the contents of this filename
// which is present in every CL
const commitMessageFileName = "/COMMIT_MSG"

// gerritCodeView implements CodeReview.
type gerritCodeReview struct {
	// gc is used to interact with the Gerrit system.
	gc gerrit.GerritInterface

	// gitiles is used to download file contents.
	gitiles *gitiles.Repo
}

// New returns a new instance of gerritCodeReview.
//
// The gerritURL value would probably be gerrit.GerritSkiaURL.
func New(local bool, gerritURL, gitilesURL string) (*gerritCodeReview, error) {
	ts, err := auth.NewDefaultTokenSource(local, auth.SCOPE_GERRIT)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	client := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	gc, err := gerrit.NewGerrit(gerritURL, client)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return &gerritCodeReview{
		gc:      gc,
		gitiles: gitiles.NewRepo(gitilesURL, client),
	}, nil
}

// ListModifiedFiles implements CodeReview.
func (cr *gerritCodeReview) ListModifiedFiles(ctx context.Context, issue codereview.Issue, ref string) ([]codereview.ListModifiedFilesResult, error) {
	// Convert Ref to patch.
	patch := path.Base(ref)
	issueInt64, err := strconv.ParseInt(string(issue), 10, 64)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	ret := []codereview.ListModifiedFilesResult{}

	files, err := cr.gc.Files(ctx, issueInt64, patch)
	if err != nil {
		return nil, skerr.Wrapf(err, "Failed retrieving list of files for %d %s", issueInt64, patch)
	}
	for filename, fileinfo := range files {
		if filename == commitMessageFileName {
			continue
		}
		ret = append(ret, codereview.ListModifiedFilesResult{
			Filename: filename,
			Deleted:  fileinfo.Status == gerrit.FileDeleted,
		})
	}
	return ret, nil
}

// GetFile implements CodeReview.
func (cr *gerritCodeReview) GetFile(ctx context.Context, filename, ref string) ([]byte, error) {
	return cr.gitiles.ReadFileAtRef(ctx, filename, ref)
}

// GetPatchsetInfo implements CodeReview.
func (cr *gerritCodeReview) GetPatchsetInfo(ctx context.Context, issue codereview.Issue) (string, bool, error) {
	changeInfo, err := cr.gc.GetChange(ctx, string(issue))
	if err != nil {
		return "", false, skerr.Wrap(err)
	}
	return changeInfo.Patchsets[len(changeInfo.Patchsets)-1].Ref, changeInfo.IsClosed(), nil
}

// Assert that gerritCodeReview implements the CodeReview interface.
var _ codereview.CodeReview = (*gerritCodeReview)(nil)
