package autoroll

/*
	Convenience functions for retrieving AutoRoll CLs.
*/

import (
	"errors"
	"fmt"
	"regexp"
	"sort"
	"time"

	github_api "github.com/google/go-github/github"
	"go.skia.org/infra/go/buildbucket"
	"go.skia.org/infra/go/comment"
	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/go/github"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

const (
	AUTOROLL_STATUS_URL = "https://autoroll.skia.org/json/status"
	POLLER_ROLLS_LIMIT  = 10
	RECENT_ROLLS_LIMIT  = 200

	ROLL_RESULT_DRY_RUN_SUCCESS     = "dry run succeeded"
	ROLL_RESULT_DRY_RUN_FAILURE     = "dry run failed"
	ROLL_RESULT_DRY_RUN_IN_PROGRESS = "dry run in progress"
	ROLL_RESULT_IN_PROGRESS         = "in progress"
	ROLL_RESULT_SUCCESS             = "succeeded"
	ROLL_RESULT_FAILURE             = "failed"

	TRYBOT_CATEGORY_CQ = "cq"

	TRYBOT_STATUS_STARTED   = "STARTED"
	TRYBOT_STATUS_COMPLETED = "COMPLETED"
	TRYBOT_STATUS_SCHEDULED = "SCHEDULED"

	TRYBOT_RESULT_CANCELED = "CANCELED"
	TRYBOT_RESULT_SUCCESS  = "SUCCESS"
	TRYBOT_RESULT_FAILURE  = "FAILURE"
)

var (
	// "RESTRICT AUTOMERGE: " is from skbug.com/8998
	ROLL_REV_REGEX = regexp.MustCompile(`^(?:(?:\[\S+\] )|(?:RESTRICT AUTOMERGE: ))?Roll \S+(?:\s+\S+)* (?:from )?(\S+)(?:(?:\.\.)|(?: to ))(\S+)(?: \(\d+ commit.*\))?\.?`)

	OPEN_ROLL_VALID_RESULTS = []string{
		ROLL_RESULT_DRY_RUN_FAILURE,
		ROLL_RESULT_DRY_RUN_IN_PROGRESS,
		ROLL_RESULT_DRY_RUN_SUCCESS,
		ROLL_RESULT_IN_PROGRESS,
	}

	DRY_RUN_RESULTS = []string{
		ROLL_RESULT_DRY_RUN_FAILURE,
		ROLL_RESULT_DRY_RUN_IN_PROGRESS,
		ROLL_RESULT_DRY_RUN_SUCCESS,
	}

	FAILURE_RESULTS = []string{
		ROLL_RESULT_DRY_RUN_FAILURE,
		ROLL_RESULT_FAILURE,
	}

	SUCCESS_RESULTS = []string{
		ROLL_RESULT_DRY_RUN_SUCCESS,
		ROLL_RESULT_SUCCESS,
	}
)

// AutoRollIssue is a struct containing the information we care about for
// AutoRoll CLs.
type AutoRollIssue struct {
	Closed         bool               `json:"closed"`
	Comments       []*comment.Comment `json:"comments"`
	Committed      bool               `json:"committed"`
	Created        time.Time          `json:"created"`
	IsDryRun       bool               `json:"isDryRun"`
	DryRunFinished bool               `json:"dryRunFinished"`
	DryRunSuccess  bool               `json:"dryRunSuccess"`
	CqFinished     bool               `json:"cqFinished"`
	CqSuccess      bool               `json:"cqSuccess"`
	Issue          int64              `json:"issue"`
	Modified       time.Time          `json:"modified"`
	Patchsets      []int64            `json:"patchSets"`
	Result         string             `json:"result"`
	RollingFrom    string             `json:"rollingFrom"`
	RollingTo      string             `json:"rollingTo"`
	Subject        string             `json:"subject"`
	TryResults     []*TryResult       `json:"tryResults"`
}

// Validate returns an error iff there is some problem with the issue.
func (i *AutoRollIssue) Validate() error {
	if i.Closed {
		if i.Result == ROLL_RESULT_DRY_RUN_IN_PROGRESS || i.Result == ROLL_RESULT_IN_PROGRESS {
			return fmt.Errorf("AutoRollIssue cannot have a Result of %q if it is Closed.", i.Result)
		}
	} else {
		if i.Committed {
			return errors.New("AutoRollIssue cannot be Committed without being Closed.")
		}
	}
	if i.CqFinished && i.IsDryRun {
		return errors.New("CqFinished cannot be true for dry runs.")
	}
	if i.DryRunFinished && !i.IsDryRun {
		return errors.New("DryRunFinished cannot be true unless the roll is a dry run.")
	}
	if i.CqSuccess && !i.CqFinished {
		return errors.New("CqSuccess cannot be true if CqFinished is not true.")
	}
	if i.DryRunSuccess && !i.DryRunFinished {
		return errors.New("DryRunSuccess cannot be true if DryRunFinished is not true.")
	}
	return nil
}

// Copy returns a copy of the AutoRollIssue.
func (i *AutoRollIssue) Copy() *AutoRollIssue {
	var commentsCpy []*comment.Comment
	if i.Comments != nil {
		commentsCpy = make([]*comment.Comment, 0, len(i.Comments))
		for _, c := range i.Comments {
			commentsCpy = append(commentsCpy, c.Copy())
		}
	}
	var patchsetsCpy []int64
	if i.Patchsets != nil {
		patchsetsCpy = make([]int64, len(i.Patchsets))
		copy(patchsetsCpy, i.Patchsets)
	}
	var tryResultsCpy []*TryResult
	if i.TryResults != nil {
		tryResultsCpy = make([]*TryResult, 0, len(i.TryResults))
		for _, t := range i.TryResults {
			tryResultsCpy = append(tryResultsCpy, t.Copy())
		}
	}
	return &AutoRollIssue{
		Closed:         i.Closed,
		Comments:       commentsCpy,
		Committed:      i.Committed,
		Created:        i.Created,
		CqFinished:     i.CqFinished,
		CqSuccess:      i.CqSuccess,
		DryRunFinished: i.DryRunFinished,
		DryRunSuccess:  i.DryRunSuccess,
		IsDryRun:       i.IsDryRun,
		Issue:          i.Issue,
		Modified:       i.Modified,
		Patchsets:      patchsetsCpy,
		Result:         i.Result,
		RollingFrom:    i.RollingFrom,
		RollingTo:      i.RollingTo,
		Subject:        i.Subject,
		TryResults:     tryResultsCpy,
	}
}

// UpdateFromGitHubPullRequest updates the AutoRollIssue instance based on the
// given PullRequest. If an error is returned, the AutoRollIssue is not changed.
func (i *AutoRollIssue) UpdateFromGitHubPullRequest(pullRequest *github_api.PullRequest) error {
	prNum := int64(pullRequest.GetNumber())
	if i.Issue == 0 {
		i.Issue = prNum
	} else if i.Issue != prNum {
		return fmt.Errorf("Pull request number %d differs from existing issue number %d!", prNum, i.Issue)
	}
	if i.IsDryRun {
		i.CqFinished = false
		i.CqSuccess = false
		i.DryRunFinished = i.AllTrybotsFinished() || pullRequest.GetState() == github.CLOSED_STATE || pullRequest.GetMerged()
		i.DryRunSuccess = (i.DryRunFinished && i.AllTrybotsSucceeded()) || pullRequest.GetMerged()
	} else {
		i.CqFinished = pullRequest.GetState() == github.CLOSED_STATE || pullRequest.GetMerged()
		i.CqSuccess = pullRequest.GetMerged()
		i.DryRunFinished = false
		i.DryRunSuccess = false
	}

	ps := make([]int64, 0, *pullRequest.Commits)
	for i := 1; i <= *pullRequest.Commits; i++ {
		ps = append(ps, int64(i))
	}
	i.Closed = pullRequest.GetState() == github.CLOSED_STATE
	i.Committed = pullRequest.GetMerged()
	i.Created = pullRequest.GetCreatedAt()
	i.Modified = pullRequest.GetUpdatedAt()
	i.Patchsets = ps
	i.Subject = pullRequest.GetTitle()
	i.Result = rollResult(i)
	return i.Validate()
}

// UpdateFromGerritChangeInfo updates the AutoRollIssue instance based on the
// given gerrit.ChangeInfo. If an error is returned, the AutoRollIssue is not
// changed.
func (i *AutoRollIssue) UpdateFromGerritChangeInfo(ci *gerrit.ChangeInfo, rollIntoAndroid bool) error {
	if i.Issue == 0 {
		i.Issue = ci.Issue
	} else if i.Issue != ci.Issue {
		return fmt.Errorf("CL ID %d differs from existing issue number %d!", ci.Issue, i.Issue)
	}
	cqFinished := false
	dryRunFinished := false
	dryRunSuccess := false
	if rollIntoAndroid {
		if _, ok := ci.Labels[gerrit.PRESUBMIT_VERIFIED_LABEL]; ok {
			for _, lb := range ci.Labels[gerrit.PRESUBMIT_VERIFIED_LABEL].All {
				if lb.Value == gerrit.PRESUBMIT_VERIFIED_LABEL_REJECTED {
					cqFinished = true
					dryRunFinished = true
					break
				} else if lb.Value == gerrit.PRESUBMIT_VERIFIED_LABEL_ACCEPTED {
					// Not marking cqSuccess or cqFinished
					// true here; those are only true if the
					// change is merged.
					dryRunFinished = true
					dryRunSuccess = true
				}
			}
		}
	} else {
		foundCqLabel := false
		foundDryRunLabel := false
		if _, ok := ci.Labels[gerrit.COMMITQUEUE_LABEL]; ok {
			for _, lb := range ci.Labels[gerrit.COMMITQUEUE_LABEL].All {
				if lb.Value == gerrit.COMMITQUEUE_LABEL_DRY_RUN {
					foundDryRunLabel = true
				} else if lb.Value == gerrit.COMMITQUEUE_LABEL_SUBMIT {
					foundCqLabel = true
				}
			}
		}
		if !foundCqLabel {
			cqFinished = true
		}
		if !foundDryRunLabel {
			dryRunFinished = true
		}
		if i.IsDryRun && dryRunFinished {
			dryRunSuccess = i.AllTrybotsSucceeded()
		}
	}

	if i.IsDryRun {
		i.CqFinished = false
		i.CqSuccess = false
		i.DryRunFinished = dryRunFinished || ci.IsClosed()
		i.DryRunSuccess = dryRunSuccess || ci.Status == gerrit.CHANGE_STATUS_MERGED
	} else {
		i.CqFinished = ci.IsClosed() || cqFinished
		i.CqSuccess = ci.Status == gerrit.CHANGE_STATUS_MERGED
		i.DryRunFinished = false
		i.DryRunSuccess = false
	}

	ps := make([]int64, 0, len(ci.Patchsets))
	for _, p := range ci.Patchsets {
		ps = append(ps, p.Number)
	}
	i.Closed = ci.IsClosed()
	i.Committed = ci.Committed
	i.Created = ci.Created
	i.Modified = ci.Updated
	i.Patchsets = ps
	i.Subject = ci.Subject
	i.Result = rollResult(i)
	return i.Validate()
}

// rollResult derives a result string for the roll.
func rollResult(roll *AutoRollIssue) string {
	if roll.IsDryRun {
		if roll.DryRunFinished {
			if roll.DryRunSuccess {
				return ROLL_RESULT_DRY_RUN_SUCCESS
			} else {
				return ROLL_RESULT_DRY_RUN_FAILURE
			}
		} else {
			return ROLL_RESULT_DRY_RUN_IN_PROGRESS
		}
	}
	if roll.CqFinished {
		if roll.CqSuccess {
			return ROLL_RESULT_SUCCESS
		} else {
			return ROLL_RESULT_FAILURE
		}
	}
	return ROLL_RESULT_IN_PROGRESS
}

// AllTrybotsFinished returns true iff all CQ trybots have finished for the
// given issue.
func (a *AutoRollIssue) AllTrybotsFinished() bool {
	for _, t := range a.TryResults {
		if t.Category != TRYBOT_CATEGORY_CQ {
			continue
		}
		if !t.Finished() {
			return false
		}
	}
	return true
}

// AtleastOneTrybotFailure returns true iff there is atleast one trybot that has
// failed for the given issue.
func (a *AutoRollIssue) AtleastOneTrybotFailure() bool {
	// For each trybot, find the most recent result.
	bots := map[string]*TryResult{}
	for _, t := range a.TryResults {
		if prev, ok := bots[t.Builder]; !ok || prev.Created.Before(t.Created) {
			bots[t.Builder] = t
		}
	}
	for _, t := range bots {
		sklog.Infof("  %s: %s (%s)", t.Builder, t.Result, t.Category)
		if t.Category != TRYBOT_CATEGORY_CQ {
			continue
		}
		if t.Failed() {
			return true
		}
	}
	return false
}

// AllTrybotsSucceeded returns true iff all CQ trybots have succeeded for the
// given issue. Note that some trybots may fail and be retried, in which case a
// successful retry counts as a success.
func (a *AutoRollIssue) AllTrybotsSucceeded() bool {
	// For each trybot, find the most recent result.
	bots := map[string]*TryResult{}
	for _, t := range a.TryResults {
		if prev, ok := bots[t.Builder]; !ok || prev.Created.Before(t.Created) {
			bots[t.Builder] = t
		}
	}
	sklog.Infof("AllTrybotsSucceeded? %d results.", len(bots))
	for _, t := range bots {
		sklog.Infof("  %s: %s (%s)", t.Builder, t.Result, t.Category)
		if t.Category != TRYBOT_CATEGORY_CQ {
			sklog.Infof("    ...skipping, not a CQ bot (category %q not %q)", t.Category, TRYBOT_CATEGORY_CQ)
			continue
		}
		if !t.Succeeded() {
			sklog.Infof("    ...failed")
			return false
		}
	}
	return true
}

// Failed returns true iff the roll failed (including dry run failure).
func (a *AutoRollIssue) Failed() bool {
	return util.In(a.Result, FAILURE_RESULTS)
}

// Succeeded returns true iff the roll succeeded (including dry run success).
func (a *AutoRollIssue) Succeeded() bool {
	return util.In(a.Result, SUCCESS_RESULTS)
}

// TryResult is a struct which contains trybot result details.
type TryResult struct {
	Builder  string    `json:"builder"`
	Category string    `json:"category"`
	Created  time.Time `json:"created_ts"`
	Result   string    `json:"result"`
	Status   string    `json:"status"`
	Url      string    `json:"url"`
}

// TryResultFromBuildbucket returns a new TryResult based on a buildbucketpb.Build.
func TryResultFromBuildbucket(b *buildbucket.Build) (*TryResult, error) {
	return &TryResult{
		Builder:  b.Parameters.BuilderName,
		Category: b.Parameters.Properties.Category,
		Created:  time.Time(b.Created),
		Result:   b.Result,
		Status:   b.Status,
		Url:      b.Url,
	}, nil
}

// TryResultsFromBuildbucket returns a slice of TryResults based on a slice of
// buildbucket.Builds.
func TryResultsFromBuildbucket(tries []*buildbucket.Build) ([]*TryResult, error) {
	res := make([]*TryResult, 0, len(tries))
	for _, t := range tries {
		tryResult, err := TryResultFromBuildbucket(t)
		if err != nil {
			return nil, err
		}
		res = append(res, tryResult)
	}
	sort.Sort(tryResultSlice(res))
	return res, nil
}

// Finished returns true iff the trybot is done running.
func (t TryResult) Finished() bool {
	return t.Status == TRYBOT_STATUS_COMPLETED
}

// Failed returns true iff the trybot completed and failed.
func (t TryResult) Failed() bool {
	return t.Finished() && t.Result == TRYBOT_RESULT_FAILURE
}

// Succeeded returns true iff the trybot completed successfully.
func (t TryResult) Succeeded() bool {
	return t.Finished() && t.Result == TRYBOT_RESULT_SUCCESS
}

// Copy returns a copy of the TryResult.
func (t *TryResult) Copy() *TryResult {
	return &TryResult{
		Builder:  t.Builder,
		Category: t.Category,
		Created:  t.Created,
		Result:   t.Result,
		Status:   t.Status,
		Url:      t.Url,
	}
}

type autoRollIssueSlice []*AutoRollIssue

func (s autoRollIssueSlice) Len() int           { return len(s) }
func (s autoRollIssueSlice) Less(i, j int) bool { return s[i].Modified.After(s[j].Modified) }
func (s autoRollIssueSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

type tryResultSlice []*TryResult

func (s tryResultSlice) Len() int           { return len(s) }
func (s tryResultSlice) Less(i, j int) bool { return s[i].Builder < s[j].Builder }
func (s tryResultSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
