// Copyright 2016 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 godash

import (
	"errors"
	"sort"
	"time"

	"github.com/google/go-github/github"
	"golang.org/x/net/context"
	"golang.org/x/sync/errgroup"
)

// Update fetches new information from GitHub for any issues modified since s was last updated.
func (s *Stats) Update(ctx context.Context, gh *github.Client, log func(string, ...interface{})) error {
	res, err := listIssues(gh, github.IssueListByRepoOptions{State: "all", Since: s.Since})
	if err != nil {
		return err
	}
	log("Github returned %d issues", len(res))
	if s.Issues == nil {
		log("Initializing new data")
		s.Issues = make(map[int]*IssueStat)
	}
	for _, issue := range res {
		s.Issues[issue.Number] = &IssueStat{
			Created:   issue.Created,
			Closed:    issue.Closed,
			Updated:   issue.Updated,
			Milestone: issue.Milestone,
		}

		if issue.Updated.After(s.Since) {
			s.Since = issue.Updated
		}
	}
	// Ingest event details. We have to do this last because it
	// can blow through our rate limit.
	var issuenums []int
	for n, issue := range s.Issues {
		if !issue.Updated.Before(s.IssueDetailSince) {
			issuenums = append(issuenums, n)
		}
	}
	if len(issuenums) == 0 {
		log("No new issues; not updating")
		return nil
	}
	sort.Sort(issueUpdatedSort{issuenums, s.Issues})

	log("Need to update %d issues", len(issuenums))

	// TODO: Limit by time instead of a fixed cap?
	if len(issuenums) > 1000 {
		issuenums = issuenums[:1000]
	}

	numch := make(chan int)
	g, ctx := errgroup.WithContext(ctx)

	for i := 0; i < 5; i++ {
		g.Go(func() error {
			for num := range numch {
				if err := s.UpdateIssue(gh, num, log); err != nil {
					return err
				}
			}
			return nil
		})
	}
	g.Go(func() error {
		defer close(numch)
		for _, num := range issuenums {
			select {
			case numch <- num:
			case <-ctx.Done():
				return ctx.Err()
			}
		}
		return nil
	})
	if err := g.Wait(); err != nil {
		// Failure to update issue details should not cause the whole update to fail.
		log("Failed updating stats: %v", err)
		return nil
	}
	s.IssueDetailSince = s.Issues[issuenums[len(issuenums)-1]].Updated
	log("Updated %d issues. Details now correct through %v", len(issuenums), s.IssueDetailSince)
	return nil
}

// UpdateIssue updates a single issue, without moving s.Since.
func (s *Stats) UpdateIssue(gh *github.Client, num int, log func(string, ...interface{})) error {
	issue := s.Issues[num]
	var milestone string
	var labels []string
	milestoneChange := func(m string, t time.Time) {
		if milestone != "" && m != milestone {
			issue.MilestoneHistory = append(issue.MilestoneHistory, MilestoneChange{milestone, t})
		}
		milestone = m
	}
	for page := 1; ; {
		events, resp, err := gh.Issues.ListIssueEvents(projectOwner, projectRepo, num, &github.ListOptions{
			Page:    page,
			PerPage: 100,
		})
		if err != nil {
			// TODO: Sometimes calls to GitHub seem to time out; if they do, perhaps we should retry?
			return err
		}
		if page == 1 {
			issue.MilestoneHistory = nil
		}
		for _, event := range events {
			evtype := getString(event.Event)
			evtime := getTime(event.CreatedAt)
			switch evtype {
			case "labeled":
				if event.Label == nil {
					continue
				}
				label := getString(event.Label.Name)
				labels = append(labels, label)
				switch label {
				case "fixed", "retracted", "done", "duplicate", "workingasintended", "wontfix", "invalid", "unfortunate", "timedout":
					// Old issues have these labels.
					issue.Closed = evtime
				}
				if label[:2] == "go" {
					milestoneChange("Go"+label[2:], evtime)
				}
			case "milestoned":
				if event.Milestone == nil {
					continue
				}
				m := getString(event.Milestone.Title)
				milestoneChange(m, evtime)
			}
		}
		if (resp.Remaining * 2) < (resp.Limit / 3) {
			// Save rate limit for the more important updates above.
			log("Out of quota (%d/%d) until %v", resp.Remaining, resp.Limit, resp.Reset)
			return errors.New("out of quota")
		}
		if resp.NextPage == 0 {
			break
		}
		page = resp.NextPage
	}
	// GitHub has a massive number of issues closed on 2014/12/8;
	// I suspect this is when they first added the closed
	// field. If we still think the issue is closed on this date,
	// that probably means we failed to correctly process the
	// labels. Log the issue's labels so we can investigate and
	// possibly add to the list of labels above.
	c := issue.Closed
	if c.Year() == 2014 && c.Month() == 12 && c.Day() == 8 {
		log("Issue %d labels: %v", num, labels)
	}
	return nil
}

type issueUpdatedSort struct {
	nums   []int
	issues map[int]*IssueStat
}

func (x issueUpdatedSort) Len() int      { return len(x.nums) }
func (x issueUpdatedSort) Swap(i, j int) { x.nums[i], x.nums[j] = x.nums[j], x.nums[i] }
func (x issueUpdatedSort) Less(i, j int) bool {
	return x.issues[x.nums[i]].Updated.Before(x.issues[x.nums[j]].Updated)
}

// Stats contains information about all GitHub issues.
//
// We track statistics for each issue to produce graphs:
//  - Issue creation time
//  - TODO(quentin): First reply time from Go team member
//  - Issue close time
//  - Issue current milestone
//  - History of issue labels + milestones
// As well as the following global info
//  - Last issue update time
//  - Last issue detail update time
type Stats struct {
	// Issues is a map of issue number to per-issue data.
	Issues map[int]*IssueStat
	// Since is the high watermark for issue update times; any
	// issues updated since Since will be refetched.
	Since time.Time
	// IssueDetailSince is the high watermark for issue details;
	// this is separate because requesting issue details uses up
	// quota, and we cannot request all issues at once.
	IssueDetailSince time.Time
}

// MilestoneChange stores a historical milestone. We store historical
// milestones separately since most issues have only ever had one
// milestone; we can save on constructing and serializing the slice
// then.
type MilestoneChange struct {
	// Name is the name of the milestone.
	Name string
	// Until is the time that the milestone was removed.
	Until time.Time
}

// IssueStat holds an individual issue's important facts.
type IssueStat struct {
	Created, Closed, Updated time.Time
	// Milestone contains the milestone the issue is currently
	// associated with.
	Milestone string
	// MilestoneHistory contains previous milestones and the time
	// the issue ceased to be assigned to that milestone. We store
	// this so the slice can be empty for most issues that have
	// only ever been associated with one milestone.
	MilestoneHistory []MilestoneChange
}
