// Copyright 2017 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 main

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"sort"
	"strings"
	"time"

	"golang.org/x/build/internal/foreach"
	"golang.org/x/build/internal/gophers"
	"golang.org/x/build/maintner"
)

type project struct {
	*maintner.GerritProject
	Changes []*change
}

// ReviewServer returns the hostname of the review server for a googlesource repo,
// e.g. "go-review.googlesource.com" for a "go.googlesource.com" server. For a
// non-googlesource.com server, it will return an empty string.
func (p *project) ReviewServer() string {
	const d = ".googlesource.com"
	s := p.Server()
	i := strings.Index(s, d)
	if i == -1 {
		return ""
	}
	return s[:i] + "-review" + d
}

type change struct {
	*maintner.GerritCL
	LastUpdate          time.Time
	FormattedLastUpdate string

	HasPlusTwo      bool
	HasPlusOne      bool
	HasMinusTwo     bool
	NoHumanComments bool
	SearchTerms     string
}

type reviewsData struct {
	Projects     []*project
	TotalChanges int

	// dirty is set if this data needs to be updated due to a corpus change.
	dirty bool
}

// handleReviews serves dev.golang.org/reviews.
func (s *server) handleReviews(t *template.Template, w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	s.cMu.RLock()
	dirty := s.data.reviews.dirty
	s.cMu.RUnlock()
	if dirty {
		s.updateReviewsData()
	}

	s.cMu.RLock()
	defer s.cMu.RUnlock()

	ownerFilter := r.FormValue("owner")
	var (
		projects     []*project
		totalChanges int
	)
	if len(ownerFilter) > 0 {
		for _, p := range s.data.reviews.Projects {
			var cs []*change
			for _, c := range p.Changes {
				if o := c.Owner(); o != nil && o.Name() == ownerFilter {
					cs = append(cs, c)
					totalChanges++
				}
			}
			if len(cs) > 0 {
				projects = append(projects, &project{GerritProject: p.GerritProject, Changes: cs})
			}
		}
	} else {
		projects = s.data.reviews.Projects
		totalChanges = s.data.reviews.TotalChanges
	}

	var buf bytes.Buffer
	if err := t.Execute(&buf, struct {
		Projects     []*project
		TotalChanges int
	}{
		Projects:     projects,
		TotalChanges: totalChanges,
	}); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if _, err := io.Copy(w, &buf); err != nil {
		log.Printf("io.Copy(w, %+v) = %v", buf, err)
		return
	}
}

func (s *server) updateReviewsData() {
	log.Println("Updating reviews data ...")
	s.cMu.Lock()
	defer s.cMu.Unlock()
	var (
		projects     []*project
		totalChanges int

		excludedProjects = map[string]bool{
			"gocloud":              true,
			"google-api-go-client": true,
		}
		deletedChanges = map[struct {
			proj string
			num  int32
		}]bool{
			{"crypto", 35958}:  true,
			{"scratch", 71730}: true,
			{"scratch", 71850}: true,
			{"scratch", 72090}: true,
			{"scratch", 72091}: true,
			{"scratch", 72110}: true,
			{"scratch", 72131}: true,
			{"tools", 93515}:   true,
		}
	)
	s.corpus.Gerrit().ForeachProjectUnsorted(func(p *maintner.GerritProject) error {
		if excludedProjects[p.Project()] {
			return nil
		}
		proj := &project{GerritProject: p}
		p.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			if deletedChanges[struct {
				proj string
				num  int32
			}{p.Project(), cl.Number}] ||
				cl.WorkInProgress() ||
				cl.Owner() == nil ||
				strings.Contains(cl.Commit.Msg, "DO NOT REVIEW") {
				return nil
			}
			var searchTerms []string
			tags := cl.Meta.Hashtags()
			if tags.Contains("wait-author") ||
				tags.Contains("wait-release") ||
				tags.Contains("wait-issue") {
				return nil
			}
			c := &change{GerritCL: cl}
			searchTerms = append(searchTerms, "repo:"+p.Project())
			searchTerms = append(searchTerms, cl.Owner().Name())
			searchTerms = append(searchTerms, "owner:"+cl.Owner().Email())
			searchTerms = append(searchTerms, "involves:"+cl.Owner().Email())
			searchTerms = append(searchTerms, fmt.Sprint(cl.Number))
			searchTerms = append(searchTerms, cl.Subject())

			c.NoHumanComments = !hasHumanComments(cl)
			if c.NoHumanComments {
				searchTerms = append(searchTerms, "t:attn")
			}
			searchTerms = append(searchTerms, searchTermsFromReviewerFields(cl)...)
			for label, votes := range cl.Metas[len(cl.Metas)-1].LabelVotes() {
				for _, val := range votes {
					if label == "Code-Review" {
						switch val {
						case -2:
							c.HasMinusTwo = true
							searchTerms = append(searchTerms, "t:-2")
						case 1:
							c.HasPlusOne = true
							searchTerms = append(searchTerms, "t:+1")
						case 2:
							c.HasPlusTwo = true
							searchTerms = append(searchTerms, "t:+2")
						}
					}
				}
			}

			c.LastUpdate = cl.Commit.CommitTime
			if len(cl.Messages) > 0 {
				c.LastUpdate = cl.Messages[len(cl.Messages)-1].Date
			}
			c.FormattedLastUpdate = c.LastUpdate.Format("2006-01-02")
			searchTerms = append(searchTerms, c.FormattedLastUpdate)
			c.SearchTerms = strings.ToLower(strings.Join(searchTerms, " "))
			proj.Changes = append(proj.Changes, c)
			totalChanges++
			return nil
		})
		sort.Slice(proj.Changes, func(i, j int) bool {
			return proj.Changes[i].LastUpdate.Before(proj.Changes[j].LastUpdate)
		})
		projects = append(projects, proj)
		return nil
	})
	sort.Slice(projects, func(i, j int) bool {
		return projects[i].Project() < projects[j].Project()
	})
	s.data.reviews.Projects = projects
	s.data.reviews.TotalChanges = totalChanges
	s.data.reviews.dirty = false
}

// hasHumanComments reports whether cl has any comments from a human on it.
func hasHumanComments(cl *maintner.GerritCL) bool {
	const (
		gobotID     = "5976@62eb7196-b449-3ce5-99f1-c037f21e1705"
		gerritbotID = "12446@62eb7196-b449-3ce5-99f1-c037f21e1705"
	)

	for _, m := range cl.Messages {
		if email := m.Author.Email(); email != gobotID && email != gerritbotID {
			return true
		}
	}
	return false
}

// searchTermsFromReviewerFields returns a slice of terms generated from
// the reviewer and cc fields of a Gerrit change.
func searchTermsFromReviewerFields(cl *maintner.GerritCL) []string {
	var searchTerms []string
	reviewers := make(map[string]bool)
	ccs := make(map[string]bool)
	for _, m := range cl.Metas {
		if !strings.Contains(m.Commit.Msg, "Reviewer:") &&
			!strings.Contains(m.Commit.Msg, "CC:") &&
			!strings.Contains(m.Commit.Msg, "Removed:") {
			continue
		}
		foreach.LineStr(m.Commit.Msg, func(ln string) error {
			if !strings.HasPrefix(ln, "Reviewer:") &&
				!strings.HasPrefix(ln, "CC:") &&
				!strings.HasPrefix(ln, "Removed:") {
				return nil
			}
			gerritID := ln[strings.LastIndexByte(ln, '<')+1 : strings.LastIndexByte(ln, '>')]
			if strings.HasPrefix(ln, "Removed:") {
				delete(reviewers, gerritID)
				delete(ccs, gerritID)
			} else if strings.HasPrefix(ln, "Reviewer:") {
				delete(ccs, gerritID)
				reviewers[gerritID] = true
			} else if strings.HasPrefix(ln, "CC:") {
				delete(reviewers, gerritID)
				ccs[gerritID] = true
			}
			return nil
		})
	}
	for r := range reviewers {
		if p := gophers.GetPerson(r); p != nil && p.Gerrit != cl.Owner().Email() {
			searchTerms = append(searchTerms, "involves:"+p.Gerrit)
			searchTerms = append(searchTerms, "reviewer:"+p.Gerrit)
		}
	}
	for r := range ccs {
		if p := gophers.GetPerson(r); p != nil && p.Gerrit != cl.Owner().Email() {
			searchTerms = append(searchTerms, "involves:"+p.Gerrit)
			searchTerms = append(searchTerms, "cc:"+p.Gerrit)
		}
	}
	return searchTerms
}
