// 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 (
	"fmt"
	"slices"
)

// A Predicate is a categorization of a [Change].
// An example of a Predicate would be "has been approved by a maintainer"
// or "author is a known contributor" or
// "waiting for response from author."
// The dashboard permits filtering and sorting CLs based on the different
// predicates they satisfy.
// A Predicate has a default score that indicates how important it is,
// but the dashboard permits using different sort orders.
type Predicate struct {
	Name        string // a short, one-word name
	Description string // a longer description
	Score       int    // default scoring value

	// The Applies function reports whether this Predicate
	// applies to a change.
	Applies func(Change) (bool, error)
}

// ChangePreds is a [Change] with a list of predicates that apply
// to that change.
type ChangePreds struct {
	Change     Change
	Predicates []*Predicate
}

// A Reject is like a [Predicate], but if the Reject applies to a [Change]
// then the Change is not put on the dashboard at all.
type Reject Predicate

// ApplyPredicates takes a [Change] and applies predicates to it.
// The reject predicates are used to determine if the change is
// reviewable; the bool result will be false if the change should
// not be reviewed, for example because it has already been committed.
func ApplyPredicates(change Change, predicates []Predicate, rejects []Reject) (ChangePreds, bool, error) {
	for i := range rejects {
		applies, err := rejects[i].Applies(change)
		if err != nil {
			return ChangePreds{}, false, err
		}
		if applies {
			return ChangePreds{}, false, nil
		}
	}

	var preds []*Predicate
	for i := range predicates {
		pred := &predicates[i]
		applies, err := pred.Applies(change)
		if err != nil {
			return ChangePreds{}, false, err
		}
		if applies {
			preds = append(preds, pred)
		}
	}

	cp := ChangePreds{
		Change:     change,
		Predicates: preds,
	}

	return cp, true, nil
}

// Some [Predicate] default scores.
const (
	ScoreImportant     = 10  // change is important
	ScoreSuggested     = 1   // change is worth looking at
	ScoreUninteresting = -1  // change is not interesting
	ScoreUnimportant   = -10 // change is not important
)

// Predicates returns a list of non-reject predicates
// that apply to a change.
func Predicates() []Predicate {
	return slices.Clone(predicates)
}

// predicates is the list of [Predicate] values that we apply to a change.
var predicates = []Predicate{
	{
		Name:        "authorMaintainer",
		Description: "the change author is a project maintainer",
		Score:       ScoreImportant,
		Applies:     authorMaintainer,
	},
	{
		Name:        "authorReviewer",
		Description: "the change author is a project reviewer",
		Score:       ScoreSuggested,
		Applies:     authorReviewer,
	},
	{
		Name:        "authorContributor",
		Description: "the change author is a project contributor",
		Score:       ScoreSuggested,
		Applies:     authorContributor,
	},
	{
		Name:        "authorMajorContributor",
		Description: "the change author is a major project contributor",
		Score:       ScoreImportant,
		Applies:     authorMajorContributor,
	},
	{
		Name:        "noMaintainerReviews",
		Description: "has no reviews from a project maintainer",
		Score:       ScoreSuggested,
		Applies:     noMaintainerReviews,
	},
}

// authorMaintainer is a [Predicate] function that reports whether the
// [Change] author is a project maintainer.
func authorMaintainer(ch Change) (bool, error) {
	switch ch.Author().Authority() {
	case AuthorityMaintainer, AuthorityOwner:
		return true, nil
	default:
		return false, nil
	}
}

// authorReviewer is a [Predicate] function that reports whether the
// [Change] author is a project reviewer.
func authorReviewer(ch Change) (bool, error) {
	switch ch.Author().Authority() {
	case AuthorityReviewer:
		return true, nil
	default:
		return false, nil
	}
}

// authorContributor is a [Predicate] function that reports whether the
// [Change] author is a known contributor: more than 10 changes contributed.
func authorContributor(ch Change) (bool, error) {
	return ch.Author().Commits() > 10, nil
}

// authorMajorContributor is a [Predicate] function that reports whether the
// [Change] author is a major contributor: more than 50 changes contributed.
func authorMajorContributor(ch Change) (bool, error) {
	return ch.Author().Commits() > 50, nil
}

// noMaintainerReviews is a [Predicate] function that reports whether the
// [Change] has not been reviewed by a maintainer.
func noMaintainerReviews(ch Change) (bool, error) {
	for _, r := range ch.Reviewed() {
		switch r.Authority() {
		case AuthorityMaintainer, AuthorityOwner:
			return false, nil
		}
	}
	return true, nil
}

// Rejects returns a list of reject predicates
// that apply to a change.
func Rejects() []Reject {
	return slices.Clone(rejects)
}

// rejects is the list of Reject values that we apply to a change.
var rejects = []Reject{
	{
		Name:        "reviewable",
		Description: "whether the change is reviewable",
		Applies:     unreviewable,
	},
}

// unreviewable is a [Reject] function that reports whether a
// [Change] is not reviewable.
func unreviewable(ch Change) (bool, error) {
	switch status := ch.Status(); status {
	case StatusReady:
		return false, nil
	case StatusSubmitted, StatusClosed, StatusDoNotReview:
		return true, nil
	default:
		return false, fmt.Errorf("reviewable predicate: change %s: unrecognized status %d", ch.ID(), status)
	}
}
