// Copyright 2016 The Vanadium 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 (
	"encoding/json"
	"fmt"
	"math"
	"sort"
	"strconv"
	"strings"
	"time"

	monitoring "google.golang.org/api/monitoring/v3"

	"v.io/x/lib/gcm"
)

const (
	defaultDuration = time.Hour
	gcmAuthTimeout  = time.Hour
)

var (
	dashboardIndexCache = []byte{}
	gcmService          *monitoring.Service
	gcmLastAuthTime     time.Time
)

type point struct {
	Timestamp int64
	Value     float64
}
type points []point

func (pts points) Len() int           { return len(pts) }
func (pts points) Less(i, j int) bool { return pts[i].Timestamp < pts[j].Timestamp }
func (pts points) Swap(i, j int)      { pts[i], pts[j] = pts[j], pts[i] }
func (pts points) Sort()              { sort.Sort(pts) }

type statsResult struct {
	SysMemUsageBytes  points
	SysMemUsagePct    points
	SysDiskUsageBytes points
	SysDiskUsagePct   points
	SysCPUUsagePct    points
	Qps               points
	Latency           points

	MinTime int64
	MaxTime int64

	NotLoggedIn bool
}

func handleDashboard(ss *serverState, rs *requestState) error {
	ctx := ss.ctx
	instance := rs.r.FormValue(paramInstance)
	if instance == "" {
		return fmt.Errorf("parameter %q required for instance name", paramInstance)
	}
	if err := checkOwner(ctx, rs.email, instance); err != nil {
		return err
	}

	tmplArgs := struct {
		ServerName,
		Instance,
		Email string
	}{
		ServerName: ss.args.serverName,
		Instance:   instance,
		Email:      rs.email,
	}
	if err := ss.args.assets.executeTemplate(rs.w, dashboardTmpl, tmplArgs); err != nil {
		return fmt.Errorf("failed to render dashboard template: %v", err)
	}
	return nil
}

// TODO(jingjin): Returning an error from handleStats will cause an error page
// to be rendered, which is not what we want when we consume the HTTP response
// via Ajax.

// handleStats responds to /stats request. It retrieves time series data
// for the given syncbase instance from GCM.
func handleStats(ss *serverState, rs *requestState) error {
	ctx := ss.ctx

	var result statsResult
	writeResult := func() error {
		// Convert result to json and return it.
		b, err := json.MarshalIndent(&result, "", "  ")
		if err != nil {
			return err
		}
		rs.w.Header().Set("Content-Type", "application/json")
		rs.w.Write(b)
		return nil
	}

	if rs.email == "" {
		result.NotLoggedIn = true
		return writeResult()
	}

	instance := rs.r.FormValue(paramInstance)
	if instance == "" {
		return fmt.Errorf("parameter %q required for instance name", paramInstance)
	}
	if err := checkOwner(ctx, rs.email, instance); err != nil {
		return err
	}

	now := time.Now()
	if gcmService == nil || now.Sub(gcmLastAuthTime) > gcmAuthTimeout {
		s, err := gcm.Authenticate(ss.args.monitoringKeyFile)
		if err != nil {
			return err
		}
		gcmService = s
		gcmLastAuthTime = now
	}

	// Get duration (default to 1h) and instance mounted name.
	duration := defaultDuration
	if strDuration := rs.r.FormValue(paramDashbordDuration); strDuration != "" {
		d, err := strconv.ParseInt(strDuration, 10, 64)
		if err != nil {
			return err
		}
		duration = time.Duration(d) * time.Second
	}

	// Get data from GCM.
	md, err := gcm.GetMetric(ss.args.dashboardGCMMetric, ss.args.dashboardGCMProject)
	if err != nil {
		return err
	}
	filters := []string{
		fmt.Sprintf("metric.type=%q", md.Type),
		// TODO(jingjin): Can we make the key be just the instance name
		// (without sb/ prefix)?
		fmt.Sprintf("metric.label.mounted_name=%q", relativeMountName(instance)),
	}
	nextPageToken := ""
	tsMap := map[string]points{}
	for {
		listCall := gcmService.Projects.TimeSeries.List(fmt.Sprintf("projects/%s", ss.args.dashboardGCMProject)).
			IntervalStartTime(now.Add(-duration).UTC().Format(time.RFC3339)).
			IntervalEndTime(now.UTC().Format(time.RFC3339)).
			Filter(strings.Join(filters, " AND ")).
			PageToken(nextPageToken)
		alignmentPeriod := getAlignmentPeriodInSeconds(duration)
		if alignmentPeriod >= 0 {
			listCall = listCall.AggregationAlignmentPeriod(fmt.Sprintf("%ds", alignmentPeriod)).AggregationPerSeriesAligner("ALIGN_MEAN")
		}
		resp, err := listCall.Do()
		if err != nil {
			return err
		}
		for _, ts := range resp.TimeSeries {
			metricName := ts.Metric.Labels["metric_name"]
			for _, pt := range ts.Points {
				epochTime, err := time.Parse(time.RFC3339, pt.Interval.EndTime)
				if err != nil {
					ctx.Errorf("Parse(%s) failed: %v", pt.Interval.EndTime, err)
					continue
				}
				tsMap[metricName] = append(tsMap[metricName], point{
					Timestamp: epochTime.Unix(),
					Value:     pt.Value.DoubleValue,
				})
			}
		}
		nextPageToken = resp.NextPageToken
		if nextPageToken == "" {
			break
		}
	}

	// Process data and put it into statsResult.
	minTime := int64(math.MaxInt64)
	maxTime := int64(0)
	for metricName, pts := range tsMap {
		tsMap[metricName].Sort()
		if pts[0].Timestamp < minTime {
			minTime = pts[0].Timestamp
		}
		if pts[len(pts)-1].Timestamp > maxTime {
			maxTime = pts[len(pts)-1].Timestamp
		}
		switch metricName {
		case "sysmem-usage-bytes":
			result.SysMemUsageBytes = pts
		case "sysmem-usage-pct":
			result.SysMemUsagePct = pts
		case "sysdisk-usage-bytes":
			result.SysDiskUsageBytes = pts
		case "sysdisk-usage-pct":
			result.SysDiskUsagePct = pts
		case "syscpu-usage-pct":
			result.SysCPUUsagePct = pts
		case "latency":
			result.Latency = pts
		case "qps":
			result.Qps = pts
		}
	}
	result.MinTime = minTime
	result.MaxTime = maxTime

	return writeResult()
}

func getAlignmentPeriodInSeconds(duration time.Duration) int {
	switch {
	case duration <= time.Hour*12:
		return -1
	case duration <= time.Hour*24:
		return 5 * 60
	case duration <= time.Hour*24*7:
		return 20 * 60
	case duration <= time.Hour*24*30:
		return 30 * 60
	default:
		return 60 * 60
	}
}
