// Copyright 2013 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"
	"net/http"
	"sort"
	"strconv"
	"strings"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
)

func perfDetailUIHandler(w http.ResponseWriter, r *http.Request) {
	d := goDash
	c := d.Context(appengine.NewContext(r))
	pc, err := GetPerfConfig(c, r)
	if err != nil {
		logErr(w, r, err)
		return
	}

	kind := r.FormValue("kind")
	builder := r.FormValue("builder")
	benchmark := r.FormValue("benchmark")
	if kind == "" {
		kind = "benchmark"
	}
	if kind != "benchmark" && kind != "builder" {
		logErr(w, r, fmt.Errorf("unknown kind %s", kind))
		return
	}

	// Fetch the new commit.
	com1 := new(Commit)
	com1.Hash = r.FormValue("commit")
	if hash, ok := knownTags[com1.Hash]; ok {
		com1.Hash = hash
	}
	if err := datastore.Get(c, com1.Key(c), com1); err != nil {
		logErr(w, r, fmt.Errorf("failed to fetch commit %s: %v", com1.Hash, err))
		return
	}
	// Fetch the associated perf result.
	ress1 := &PerfResult{CommitHash: com1.Hash}
	if err := datastore.Get(c, ress1.Key(c), ress1); err != nil {
		logErr(w, r, fmt.Errorf("failed to fetch perf result %s: %v", com1.Hash, err))
		return
	}

	// Fetch the old commit.
	var ress0 *PerfResult
	com0 := new(Commit)
	com0.Hash = r.FormValue("commit0")
	if hash, ok := knownTags[com0.Hash]; ok {
		com0.Hash = hash
	}
	if com0.Hash != "" {
		// Have an exact commit hash, fetch directly.
		if err := datastore.Get(c, com0.Key(c), com0); err != nil {
			logErr(w, r, fmt.Errorf("failed to fetch commit %s: %v", com0.Hash, err))
			return
		}
		ress0 = &PerfResult{CommitHash: com0.Hash}
		if err := datastore.Get(c, ress0.Key(c), ress0); err != nil {
			logErr(w, r, fmt.Errorf("failed to fetch perf result for %s: %v", com0.Hash, err))
			return
		}
	} else {
		// Don't have the commit hash, find the previous commit to compare.
		rc := MakePerfResultCache(c, com1, false)
		ress0, err = rc.NextForComparison(com1.Num, "")
		if err != nil {
			logErr(w, r, err)
			return
		}
		if ress0 == nil {
			logErr(w, r, fmt.Errorf("no previous commit with results"))
			return
		}
		// Now that we know the right result, fetch the commit.
		com0.Hash = ress0.CommitHash
		if err := datastore.Get(c, com0.Key(c), com0); err != nil {
			logErr(w, r, fmt.Errorf("failed to fetch commit %s: %v", com0.Hash, err))
			return
		}
	}

	res0 := ress0.ParseData()
	res1 := ress1.ParseData()
	var benchmarks []*uiPerfDetailBenchmark
	var list []string
	if kind == "builder" {
		list = pc.BenchmarksForBuilder(builder)
	} else {
		list = pc.BuildersForBenchmark(benchmark)
	}
	for _, other := range list {
		if kind == "builder" {
			benchmark = other
		} else {
			builder = other
		}
		var procs []*uiPerfDetailProcs
		allProcs := pc.ProcList(builder)
		for _, p := range allProcs {
			BenchProcs := fmt.Sprintf("%v-%v", benchmark, p)
			if res0[builder] == nil || res0[builder][BenchProcs] == nil {
				continue
			}
			pp := &uiPerfDetailProcs{Procs: p}
			for metric, val := range res0[builder][BenchProcs].Metrics {
				var pm uiPerfDetailMetric
				pm.Name = metric
				pm.Val0 = fmt.Sprintf("%v", val)
				val1 := uint64(0)
				if res1[builder] != nil && res1[builder][BenchProcs] != nil {
					val1 = res1[builder][BenchProcs].Metrics[metric]
				}
				pm.Val1 = fmt.Sprintf("%v", val1)
				v0 := val
				v1 := val1
				valf := perfDiff(v0, v1)
				pm.Delta = fmt.Sprintf("%+.2f%%", valf)
				pm.Style = perfChangeStyle(pc, valf, builder, BenchProcs, pm.Name)
				pp.Metrics = append(pp.Metrics, pm)
			}
			sort.Sort(pp.Metrics)
			for artifact, hash := range res0[builder][BenchProcs].Artifacts {
				var pm uiPerfDetailMetric
				pm.Val0 = fmt.Sprintf("%v", artifact)
				pm.Link0 = fmt.Sprintf("log/%v", hash)
				pm.Val1 = fmt.Sprintf("%v", artifact)
				if res1[builder] != nil && res1[builder][BenchProcs] != nil && res1[builder][BenchProcs].Artifacts[artifact] != "" {
					pm.Link1 = fmt.Sprintf("log/%v", res1[builder][BenchProcs].Artifacts[artifact])
				}
				pp.Metrics = append(pp.Metrics, pm)
			}
			procs = append(procs, pp)
		}
		benchmarks = append(benchmarks, &uiPerfDetailBenchmark{other, procs})
	}

	cfg := new(uiPerfConfig)
	for _, v := range pc.BuildersForBenchmark("") {
		cfg.Builders = append(cfg.Builders, uiPerfConfigElem{v, v == builder})
	}
	for _, v := range pc.BenchmarksForBuilder("") {
		cfg.Benchmarks = append(cfg.Benchmarks, uiPerfConfigElem{v, v == benchmark})
	}

	data := &uiPerfDetailTemplateData{d, cfg, kind == "builder", com0, com1, benchmarks}

	var buf bytes.Buffer
	if err := uiPerfDetailTemplate.Execute(&buf, data); err != nil {
		logErr(w, r, err)
		return
	}

	buf.WriteTo(w)
}

func perfResultSplit(s string) (builder string, benchmark string, procs int) {
	s1 := strings.Split(s, "|")
	s2 := strings.Split(s1[1], "-")
	procs, _ = strconv.Atoi(s2[1])
	return s1[0], s2[0], procs
}

type uiPerfDetailTemplateData struct {
	Dashboard   *Dashboard
	Config      *uiPerfConfig
	KindBuilder bool
	Commit0     *Commit
	Commit1     *Commit
	Benchmarks  []*uiPerfDetailBenchmark
}

type uiPerfDetailBenchmark struct {
	Name  string
	Procs []*uiPerfDetailProcs
}

type uiPerfDetailProcs struct {
	Procs   int
	Metrics uiPerfDetailMetrics
}

type uiPerfDetailMetric struct {
	Name  string
	Val0  string
	Val1  string
	Link0 string
	Link1 string
	Delta string
	Style string
}

type uiPerfDetailMetrics []uiPerfDetailMetric

func (l uiPerfDetailMetrics) Len() int           { return len(l) }
func (l uiPerfDetailMetrics) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l uiPerfDetailMetrics) Less(i, j int) bool { return l[i].Name < l[j].Name }

var uiPerfDetailTemplate = template.Must(
	template.New("perf_detail.html").Funcs(tmplFuncs).ParseFiles("app/appengine/perf_detail.html"),
)
