// 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"
	"slices"
	"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 _, v := range slices.Backward(cl.Metas) {
			if !strings.Contains(v.Commit.Msg, "autogenerated:gerrit") {
				continue
			}

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