// Copyright 2019 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"
	"html/template"
	"io"
	"log"
	"math"
	"net/http"
	"strings"
	"time"

	"golang.org/x/build/maintner"
)

// handleStats serves dev.golang.org/stats.
func (s *server) handleStats(t *template.Template, w http.ResponseWriter, r *http.Request) {
	s.cMu.RLock()
	dirty := s.data.stats.dirty
	s.cMu.RUnlock()
	if dirty {
		s.updateStatsData()
	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	var buf bytes.Buffer
	s.cMu.RLock()
	defer s.cMu.RUnlock()
	data := struct {
		DataJSON any
	}{
		DataJSON: s.data.stats,
	}
	if err := t.Execute(&buf, data); 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
	}
}

type statsData struct {
	Charts []*chart

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

// A chart holds data used by the Google Charts JavaScript API to render
// an interactive visualization.
type chart struct {
	Title   string         `json:"title"`
	Columns []*chartColumn `json:"columns"`
	Data    [][]any        `json:"data"`
}

// A chartColumn is analogous to a Google Charts DataTable column.
type chartColumn struct {
	// Type is the data type of the values of the column.
	// Supported values are 'string', 'number', 'boolean',
	// 'timeofday', 'date', and 'datetime'.
	Type string `json:"type"`

	// Label is an optional label for the column.
	Label string `json:"label"`
}

func (s *server) updateStatsData() {
	log.Println("Updating stats data ...")
	s.cMu.Lock()
	defer s.cMu.Unlock()

	var (
		windowStart = time.Now().Add(-1 * 365 * 24 * time.Hour)
		intervals   []*clInterval
	)
	s.corpus.Gerrit().ForeachProjectUnsorted(filterProjects(func(p *maintner.GerritProject) error {
		p.ForeachCLUnsorted(withoutDeletedCLs(p, func(cl *maintner.GerritCL) error {
			closed := cl.Status == "merged" || cl.Status == "abandoned"

			// Discard CL if closed and last updated before windowStart.
			if closed && cl.Meta.Commit.CommitTime.Before(windowStart) {
				return nil
			}
			intervals = append(intervals, newIntervalFromCL(cl))
			return nil
		}))
		return nil
	}))

	var chartData [][]any
	for t0, t1 := windowStart, windowStart.Add(24*time.Hour); t0.Before(time.Now()); t0, t1 = t0.Add(24*time.Hour), t1.Add(24*time.Hour) {
		var (
			open       int
			withIssues int
		)

		for _, i := range intervals {
			if !i.intersects(t0, t1) {
				continue
			}
			open++
			if len(i.cl.GitHubIssueRefs) > 0 {
				withIssues++
			}
		}
		chartData = append(chartData, []any{
			t0, open, withIssues,
		})
	}
	cols := []*chartColumn{
		{Type: "date", Label: "date"},
		{Type: "number", Label: "All CLs"},
		{Type: "number", Label: "With issues"},
	}
	var charts []*chart
	charts = append(charts, &chart{
		Title:   "Open CLs (1 Year)",
		Columns: cols,
		Data:    chartData,
	})
	charts = append(charts, &chart{
		Title:   "Open CLs (30 Days)",
		Columns: cols,
		Data:    chartData[len(chartData)-30:],
	})
	charts = append(charts, &chart{
		Title:   "Open CLs (7 Days)",
		Columns: cols,
		Data:    chartData[len(chartData)-7:],
	})
	s.data.stats.Charts = charts
}

// A clInterval describes a time period during which a CL is open.
// points on the interval are seconds since the epoch.
type clInterval struct {
	start, end int64 // seconds since epoch
	cl         *maintner.GerritCL
}

// returns true iff the interval contains any seconds
// in the timespan [t0,t1]. t0 must be before t1.
func (i *clInterval) intersects(t0, t1 time.Time) bool {
	if t1.Before(t0) {
		panic("t0 cannot be before t1")
	}
	return i.end >= t0.Unix() && i.start <= t1.Unix()
}

func newIntervalFromCL(cl *maintner.GerritCL) *clInterval {
	interval := &clInterval{
		start: cl.Created.Unix(),
		end:   math.MaxInt64,
		cl:    cl,
	}

	closed := cl.Status == "merged" || cl.Status == "abandoned"
	if closed {
		for i := len(cl.Metas) - 1; i >= 0; i-- {
			if !strings.Contains(cl.Metas[i].Commit.Msg, "autogenerated:gerrit") {
				continue
			}

			if strings.Contains(cl.Metas[i].Commit.Msg, "autogenerated:gerrit:merged") ||
				strings.Contains(cl.Metas[i].Commit.Msg, "autogenerated:gerrit:abandon") {
				interval.end = cl.Metas[i].Commit.CommitTime.Unix()
			}
		}
		if interval.end == math.MaxInt64 {
			log.Printf("Unable to determine close time of CL: %+v", cl)
		}
	}
	return interval
}
