// Copyright 2024 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 reviews

import (
	"slices"
	"strconv"
	"time"

	"golang.org/x/oscar/internal/gerrit"
)

// GerritReviewClient is a [gerrit.Client] with a mapping
// from account e-mail addresses to [Account] data.
// We do things this way because a lot of Gerrit change
// data is more or less the same for any Gerrit project,
// but account information is not.
type GerritReviewClient struct {
	GClient  *gerrit.Client
	Project  string
	Accounts AccountLookup
}

// GerritChange implements [Change] for a Gerrit CL.
type GerritChange struct {
	Client *GerritReviewClient
	Change *gerrit.Change
}

// ID returns the change ID.
func (gc *GerritChange) ID() string {
	return strconv.Itoa(gc.Client.GClient.ChangeNumber(gc.Change))
}

// Status returns the change status.
func (gc *GerritChange) Status() Status {
	switch gc.Client.GClient.ChangeStatus(gc.Change) {
	case "MERGED":
		return StatusSubmitted
	case "ABANDONED":
		return StatusClosed
	default:
		if gc.Client.GClient.ChangeWorkInProgress(gc.Change) {
			return StatusDoNotReview
		}
		return StatusReady
	}
}

// Author returns the change author.
func (gc *GerritChange) Author() Account {
	gai := gc.Client.GClient.ChangeOwner(gc.Change)
	return gc.Client.Accounts.Lookup(gai.Email)
}

// Created returns the time that the change was created.
func (gc *GerritChange) Created() time.Time {
	ct := gc.Client.GClient.ChangeTimes(gc.Change)
	return ct.Created
}

// Updated returns the time that the change was last updated.
func (gc *GerritChange) Updated() time.Time {
	ct := gc.Client.GClient.ChangeTimes(gc.Change)
	return ct.Updated
}

// UpdatedByAuthor returns the time that the change was updated by the
// original author.
func (gc *GerritChange) UpdatedByAuthor() time.Time {
	author := gc.Client.GClient.ChangeOwner(gc.Change)
	revs := gc.Client.GClient.ChangeRevisions(gc.Change)
	for _, rev := range slices.Backward(revs) {
		if rev.Uploader.Email == author.Email {
			return rev.Created.Time()
		}
	}
	return time.Time{}
}

// Subject returns the change subject.
func (gc *GerritChange) Subject() string {
	return gc.Client.GClient.ChangeSubject(gc.Change)
}

// Description returns the full change description.
func (gc *GerritChange) Description() string {
	return gc.Client.GClient.ChangeDescription(gc.Change)
}

// Reviewers returns the assigned reviewers.
func (gc *GerritChange) Reviewers() []Account {
	reviewers := gc.Client.GClient.ChangeReviewers(gc.Change)
	ret := make([]Account, 0, len(reviewers))
	for _, rev := range reviewers {
		ret = append(ret, gc.Client.Accounts.Lookup(rev.Email))
	}
	return ret
}

// Reviewed returns the accounts that have reviewed the change.
// We treat any account that has sent a message about the change
// as a reviewer.
func (gc *GerritChange) Reviewed() []Account {
	reviewers := make(map[string]bool)
	msgs := gc.Client.GClient.ChangeMessages(gc.Change)
	for _, msg := range msgs {
		if msg.RealAuthor != nil {
			reviewers[msg.RealAuthor.Email] = true
		} else if msg.Author != nil {
			reviewers[msg.Author.Email] = true
		}
	}

	num := gc.Client.GClient.ChangeNumber(gc.Change)
	commentMap := gc.Client.GClient.Comments(gc.Client.Project, num)
	for _, comments := range commentMap {
		for _, comment := range comments {
			if comment.Author != nil {
				reviewers[comment.Author.Email] = true
			}
		}
	}

	owner := gc.Client.GClient.ChangeOwner(gc.Change)
	delete(reviewers, owner.Email)

	ret := make([]Account, 0, len(reviewers))
	for email := range reviewers {
		ret = append(ret, gc.Client.Accounts.Lookup(email))
	}
	return ret
}

// Needs returns missing requirements for submittal.
// This implementation does what we can, but most projects will need
// their own version of this method.
func (gc *GerritChange) Needs() Needs {
	hasReview, hasMaintainerReview := false, false
	for _, review := range gc.Reviewed() {
		switch review.Authority() {
		case AuthorityReviewer:
			hasReview = true
		case AuthorityMaintainer, AuthorityOwner:
			hasMaintainerReview = true
		}
	}
	if hasMaintainerReview {
		// We don't really know if the change can be submitted.
		return 0
	} else if hasReview {
		return NeedsMaintainerReview
	} else {
		return NeedsReview
	}
}
