// Copyright 2011 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"
	"compress/gzip"
	"context"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"time"

	"golang.org/x/build/app/cache"
	"golang.org/x/build/dashboard"
	"golang.org/x/build/internal/loghash"
	"google.golang.org/appengine/datastore"
)

const (
	maxDatastoreStringLen = 500
	PerfRunLength         = 1024
)

// A Package describes a package that is listed on the dashboard.
type Package struct {
	Kind    string // "subrepo", "external", or empty for the main Go tree
	Name    string // "Go", "arch", "net", ...
	Path    string // empty for the main Go tree, else "golang.org/x/foo"
	NextNum int    // Num of the next head Commit
}

func (p *Package) String() string {
	return fmt.Sprintf("%s: %q", p.Path, p.Name)
}

func (p *Package) Key(c context.Context) *datastore.Key {
	key := p.Path
	if key == "" {
		key = "go"
	}
	return datastore.NewKey(c, "Package", key, 0, nil)
}

// LastCommit returns the most recent Commit for this Package.
func (p *Package) LastCommit(c context.Context) (*Commit, error) {
	var commits []*Commit
	_, err := datastore.NewQuery("Commit").
		Ancestor(p.Key(c)).
		Order("-Time").
		Limit(1).
		GetAll(c, &commits)
	if err != nil {
		return nil, err
	}
	if len(commits) != 1 {
		return nil, datastore.ErrNoSuchEntity
	}
	return commits[0], nil
}

// GetPackage fetches a Package by path from the datastore.
func GetPackage(c context.Context, path string) (*Package, error) {
	p := &Package{Path: path}
	err := datastore.Get(c, p.Key(c), p)
	if err == datastore.ErrNoSuchEntity {
		return nil, fmt.Errorf("package %q not found", path)
	}
	return p, err
}

type builderAndGoHash struct {
	builder, goHash string
}

// A Commit describes an individual commit in a package.
//
// Each Commit entity is a descendant of its associated Package entity.
// In other words, all Commits with the same PackagePath belong to the same
// datastore entity group.
type Commit struct {
	PackagePath string // (empty for main repo commits)
	Hash        string
	ParentHash  string
	Num         int // Internal monotonic counter unique to this package.

	User              string
	Desc              string `datastore:",noindex"`
	Time              time.Time
	NeedsBenchmarking bool
	TryPatch          bool
	Branch            string

	// ResultData is the Data string of each build Result for this Commit.
	// For non-Go commits, only the Results for the current Go tip, weekly,
	// and release Tags are stored here. This is purely de-normalized data.
	// The complete data set is stored in Result entities.
	ResultData []string `datastore:",noindex"`

	// PerfResults holds a set of “builder|benchmark” tuples denoting
	// what benchmarks have been executed on the commit.
	PerfResults []string `datastore:",noindex"`

	FailNotificationSent bool

	buildingURLs map[builderAndGoHash]string
}

func (com *Commit) Key(c context.Context) *datastore.Key {
	if com.Hash == "" {
		panic("tried Key on Commit with empty Hash")
	}
	p := Package{Path: com.PackagePath}
	key := com.PackagePath + "|" + com.Hash
	return datastore.NewKey(c, "Commit", key, 0, p.Key(c))
}

func (c *Commit) Valid() error {
	if !validHash(c.Hash) {
		return errors.New("invalid Hash")
	}
	if c.ParentHash != "" && !validHash(c.ParentHash) { // empty is OK
		return errors.New("invalid ParentHash")
	}
	return nil
}

func putCommit(c context.Context, com *Commit) error {
	if err := com.Valid(); err != nil {
		return fmt.Errorf("putting Commit: %v", err)
	}
	if com.Num == 0 && com.ParentHash != "0000" { // 0000 is used in tests
		return fmt.Errorf("putting Commit: invalid Num (must be > 0)")
	}
	if _, err := datastore.Put(c, com.Key(c), com); err != nil {
		return fmt.Errorf("putting Commit: %v", err)
	}
	return nil
}

// each result line is approx 105 bytes. This constant is a tradeoff between
// build history and the AppEngine datastore limit of 1mb.
const maxResults = 1000

// AddResult adds the denormalized Result data to the Commit's ResultData field.
// It must be called from inside a datastore transaction.
func (com *Commit) AddResult(c context.Context, r *Result) error {
	if err := datastore.Get(c, com.Key(c), com); err != nil {
		return fmt.Errorf("getting Commit: %v", err)
	}

	var resultExists bool
	for i, s := range com.ResultData {
		// if there already exists result data for this builder at com, overwrite it.
		if strings.HasPrefix(s, r.Builder+"|") && strings.HasSuffix(s, "|"+r.GoHash) {
			resultExists = true
			com.ResultData[i] = r.Data()
		}
	}
	if !resultExists {
		// otherwise, add the new result data for this builder.
		com.ResultData = trim(append(com.ResultData, r.Data()), maxResults)
	}
	return putCommit(c, com)
}

// removeResult removes the denormalized Result data from the ResultData field
// for the given builder and go hash.
// It must be called from within the datastore transaction that gets and puts
// the Commit. Note this is slightly different to AddResult, above.
func (com *Commit) RemoveResult(r *Result) {
	var rd []string
	for _, s := range com.ResultData {
		if strings.HasPrefix(s, r.Builder+"|") && strings.HasSuffix(s, "|"+r.GoHash) {
			continue
		}
		rd = append(rd, s)
	}
	com.ResultData = rd
}

// AddPerfResult remembers that the builder has run the benchmark on the commit.
// It must be called from inside a datastore transaction.
func (com *Commit) AddPerfResult(c context.Context, builder, benchmark string) error {
	if err := datastore.Get(c, com.Key(c), com); err != nil {
		return fmt.Errorf("getting Commit: %v", err)
	}
	if !com.NeedsBenchmarking {
		return fmt.Errorf("trying to add perf result to Commit(%v) that does not require benchmarking", com.Hash)
	}
	s := builder + "|" + benchmark
	for _, v := range com.PerfResults {
		if v == s {
			return nil
		}
	}
	com.PerfResults = append(com.PerfResults, s)
	return putCommit(c, com)
}

func trim(s []string, n int) []string {
	l := min(len(s), n)
	return s[len(s)-l:]
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// Result returns the build Result for this Commit for the given builder/goHash.
func (c *Commit) Result(builder, goHash string) *Result {
	for _, r := range c.ResultData {
		if !strings.HasPrefix(r, builder) {
			// Avoid strings.SplitN alloc in the common case.
			continue
		}
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 || p[0] != builder || p[3] != goHash {
			continue
		}
		return partsToResult(c, p)
	}
	if u, ok := c.buildingURLs[builderAndGoHash{builder, goHash}]; ok {
		return &Result{
			Builder:     builder,
			BuildingURL: u,
			Hash:        c.Hash,
			GoHash:      goHash,
		}
	}
	return nil
}

// isUntested reports whether a cell in the build.golang.org grid is
// an untested configuration.
//
// repo is "go", "net", etc.
// branch is the branch of repo "master" or "release-branch.go1.12"
// goBranch applies only if repo != "go" and is of form "master" or "release-branch.go1.N"
//
// As a special case, "tip" is an alias for "master", since this app
// still uses a bunch of hg terms from when we used hg.
func isUntested(builder, repo, branch, goBranch string) bool {
	if branch == "tip" {
		branch = "master"
	}
	if goBranch == "tip" {
		goBranch = "master"
	}
	bc, ok := dashboard.Builders[builder]
	if !ok {
		// Not managed by coordinator. Might be an old-style builder.
		// TODO: remove this once the old-style builders are all dead.
		return false
	}
	return !bc.BuildsRepoPostSubmit(repo, branch, goBranch)
}

// Results returns the build Results for this Commit.
func (c *Commit) Results() (results []*Result) {
	for _, r := range c.ResultData {
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 {
			continue
		}
		results = append(results, partsToResult(c, p))
	}
	return
}

func (c *Commit) ResultGoHashes() []string {
	// For the main repo, just return the empty string
	// (there's no corresponding main repo hash for a main repo Commit).
	// This function is only really useful for sub-repos.
	if c.PackagePath == "" {
		return []string{""}
	}
	var hashes []string
	for _, r := range c.ResultData {
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 {
			continue
		}
		// Append only new results (use linear scan to preserve order).
		if !contains(hashes, p[3]) {
			hashes = append(hashes, p[3])
		}
	}
	// Return results in reverse order (newest first).
	reverse(hashes)
	return hashes
}

func contains(t []string, s string) bool {
	for _, s2 := range t {
		if s2 == s {
			return true
		}
	}
	return false
}

func reverse(s []string) {
	for i := 0; i < len(s)/2; i++ {
		j := len(s) - i - 1
		s[i], s[j] = s[j], s[i]
	}
}

// A CommitRun provides summary information for commits [StartCommitNum, StartCommitNum + PerfRunLength).
// Descendant of Package.
type CommitRun struct {
	PackagePath       string // (empty for main repo commits)
	StartCommitNum    int
	Hash              []string    `datastore:",noindex"`
	User              []string    `datastore:",noindex"`
	Desc              []string    `datastore:",noindex"` // Only first line.
	Time              []time.Time `datastore:",noindex"`
	NeedsBenchmarking []bool      `datastore:",noindex"`
}

func (cr *CommitRun) Key(c context.Context) *datastore.Key {
	p := Package{Path: cr.PackagePath}
	key := strconv.Itoa(cr.StartCommitNum)
	return datastore.NewKey(c, "CommitRun", key, 0, p.Key(c))
}

// GetCommitRun loads and returns CommitRun that contains information
// for commit commitNum.
func GetCommitRun(c context.Context, commitNum int) (*CommitRun, error) {
	cr := &CommitRun{StartCommitNum: commitNum / PerfRunLength * PerfRunLength}
	err := datastore.Get(c, cr.Key(c), cr)
	if err != nil && err != datastore.ErrNoSuchEntity {
		return nil, fmt.Errorf("getting CommitRun: %v", err)
	}
	if len(cr.Hash) != PerfRunLength {
		cr.Hash = make([]string, PerfRunLength)
		cr.User = make([]string, PerfRunLength)
		cr.Desc = make([]string, PerfRunLength)
		cr.Time = make([]time.Time, PerfRunLength)
		cr.NeedsBenchmarking = make([]bool, PerfRunLength)
	}
	return cr, nil
}

func (cr *CommitRun) AddCommit(c context.Context, com *Commit) error {
	if com.Num < cr.StartCommitNum || com.Num >= cr.StartCommitNum+PerfRunLength {
		return fmt.Errorf("AddCommit: commit num %v out of range [%v, %v)",
			com.Num, cr.StartCommitNum, cr.StartCommitNum+PerfRunLength)
	}
	i := com.Num - cr.StartCommitNum
	// Be careful with string lengths,
	// we need to fit 1024 commits into 1 MB.
	cr.Hash[i] = com.Hash
	cr.User[i] = shortDesc(com.User)
	cr.Desc[i] = shortDesc(com.Desc)
	cr.Time[i] = com.Time
	cr.NeedsBenchmarking[i] = com.NeedsBenchmarking
	if _, err := datastore.Put(c, cr.Key(c), cr); err != nil {
		return fmt.Errorf("putting CommitRun: %v", err)
	}
	return nil
}

// GetCommits returns [startCommitNum, startCommitNum+n) commits.
// Commits information is partial (obtained from CommitRun),
// do not store them back into datastore.
func GetCommits(c context.Context, startCommitNum, n int) ([]*Commit, error) {
	if startCommitNum < 0 || n <= 0 {
		return nil, fmt.Errorf("GetCommits: invalid args (%v, %v)", startCommitNum, n)
	}

	p := &Package{}
	t := datastore.NewQuery("CommitRun").
		Ancestor(p.Key(c)).
		Filter("StartCommitNum >=", startCommitNum/PerfRunLength*PerfRunLength).
		Order("StartCommitNum").
		Limit(100).
		Run(c)

	res := make([]*Commit, n)
	for {
		cr := new(CommitRun)
		_, err := t.Next(cr)
		if err == datastore.Done {
			break
		}
		if err != nil {
			return nil, err
		}
		if cr.StartCommitNum >= startCommitNum+n {
			break
		}
		// Calculate start index for copying.
		i := 0
		if cr.StartCommitNum < startCommitNum {
			i = startCommitNum - cr.StartCommitNum
		}
		// Calculate end index for copying.
		e := PerfRunLength
		if cr.StartCommitNum+e > startCommitNum+n {
			e = startCommitNum + n - cr.StartCommitNum
		}
		for ; i < e; i++ {
			com := new(Commit)
			com.Hash = cr.Hash[i]
			com.User = cr.User[i]
			com.Desc = cr.Desc[i]
			com.Time = cr.Time[i]
			com.NeedsBenchmarking = cr.NeedsBenchmarking[i]
			res[cr.StartCommitNum-startCommitNum+i] = com
		}
		if e != PerfRunLength {
			break
		}
	}
	return res, nil
}

// partsToResult converts a Commit and ResultData substrings to a Result.
func partsToResult(c *Commit, p []string) *Result {
	return &Result{
		Builder:     p[0],
		Hash:        c.Hash,
		PackagePath: c.PackagePath,
		GoHash:      p[3],
		OK:          p[1] == "true",
		LogHash:     p[2],
	}
}

// A Result describes a build result for a Commit on an OS/architecture.
//
// Each Result entity is a descendant of its associated Package entity.
type Result struct {
	PackagePath string // (empty for Go commits)
	Builder     string // "os-arch[-note]"
	Hash        string

	// The Go Commit this was built against (empty for Go commits).
	GoHash string

	BuildingURL string `datastore:"-"` // non-empty if currently building
	OK          bool
	Log         string `datastore:"-"`        // for JSON unmarshaling only
	LogHash     string `datastore:",noindex"` // Key to the Log record.

	RunTime int64 // time to build+test in nanoseconds
}

func (r *Result) Key(c context.Context) *datastore.Key {
	p := Package{Path: r.PackagePath}
	key := r.Builder + "|" + r.PackagePath + "|" + r.Hash + "|" + r.GoHash
	return datastore.NewKey(c, "Result", key, 0, p.Key(c))
}

func (r *Result) Valid() error {
	if !validHash(r.Hash) {
		return errors.New("invalid Hash")
	}
	if r.PackagePath != "" && !validHash(r.GoHash) {
		return errors.New("invalid GoHash")
	}
	return nil
}

// Data returns the Result in string format
// to be stored in Commit's ResultData field.
func (r *Result) Data() string {
	return fmt.Sprintf("%v|%v|%v|%v", r.Builder, r.OK, r.LogHash, r.GoHash)
}

// A PerfResult describes all benchmarking result for a Commit.
// Descendant of Package.
type PerfResult struct {
	PackagePath string
	CommitHash  string
	CommitNum   int
	Data        []string `datastore:",noindex"` // "builder|benchmark|ok|metric1=val1|metric2=val2|file:log=hash|file:cpuprof=hash"

	// Local cache with parsed Data.
	// Maps builder->benchmark->ParsedPerfResult.
	parsedData map[string]map[string]*ParsedPerfResult
}

type ParsedPerfResult struct {
	OK        bool
	Metrics   map[string]uint64
	Artifacts map[string]string
}

func (r *PerfResult) Key(c context.Context) *datastore.Key {
	p := Package{Path: r.PackagePath}
	key := r.CommitHash
	return datastore.NewKey(c, "PerfResult", key, 0, p.Key(c))
}

// AddResult add the benchmarking result to r.
// Existing result for the same builder/benchmark is replaced if already exists.
// Returns whether the result was already present.
func (r *PerfResult) AddResult(req *PerfRequest) bool {
	present := false
	str := fmt.Sprintf("%v|%v|", req.Builder, req.Benchmark)
	for i, s := range r.Data {
		if strings.HasPrefix(s, str) {
			present = true
			last := len(r.Data) - 1
			r.Data[i] = r.Data[last]
			r.Data = r.Data[:last]
			break
		}
	}
	ok := "ok"
	if !req.OK {
		ok = "false"
	}
	str += ok
	for _, m := range req.Metrics {
		str += fmt.Sprintf("|%v=%v", m.Type, m.Val)
	}
	for _, a := range req.Artifacts {
		str += fmt.Sprintf("|file:%v=%v", a.Type, a.Body)
	}
	r.Data = append(r.Data, str)
	r.parsedData = nil
	return present
}

func (r *PerfResult) ParseData() map[string]map[string]*ParsedPerfResult {
	if r.parsedData != nil {
		return r.parsedData
	}
	res := make(map[string]map[string]*ParsedPerfResult)
	for _, str := range r.Data {
		ss := strings.Split(str, "|")
		builder := ss[0]
		bench := ss[1]
		ok := ss[2]
		m := res[builder]
		if m == nil {
			m = make(map[string]*ParsedPerfResult)
			res[builder] = m
		}
		var p ParsedPerfResult
		p.OK = ok == "ok"
		p.Metrics = make(map[string]uint64)
		p.Artifacts = make(map[string]string)
		for _, entry := range ss[3:] {
			if strings.HasPrefix(entry, "file:") {
				ss1 := strings.Split(entry[len("file:"):], "=")
				p.Artifacts[ss1[0]] = ss1[1]
			} else {
				ss1 := strings.Split(entry, "=")
				val, _ := strconv.ParseUint(ss1[1], 10, 64)
				p.Metrics[ss1[0]] = val
			}
		}
		m[bench] = &p
	}
	r.parsedData = res
	return res
}

// A PerfMetricRun entity holds a set of metric values for builder/benchmark/metric
// for commits [StartCommitNum, StartCommitNum + PerfRunLength).
// Descendant of Package.
type PerfMetricRun struct {
	PackagePath    string
	Builder        string
	Benchmark      string
	Metric         string // e.g. realtime, cputime, gc-pause
	StartCommitNum int
	Vals           []int64 `datastore:",noindex"`
}

func (m *PerfMetricRun) Key(c context.Context) *datastore.Key {
	p := Package{Path: m.PackagePath}
	key := m.Builder + "|" + m.Benchmark + "|" + m.Metric + "|" + strconv.Itoa(m.StartCommitNum)
	return datastore.NewKey(c, "PerfMetricRun", key, 0, p.Key(c))
}

// GetPerfMetricRun loads and returns PerfMetricRun that contains information
// for commit commitNum.
func GetPerfMetricRun(c context.Context, builder, benchmark, metric string, commitNum int) (*PerfMetricRun, error) {
	startCommitNum := commitNum / PerfRunLength * PerfRunLength
	m := &PerfMetricRun{Builder: builder, Benchmark: benchmark, Metric: metric, StartCommitNum: startCommitNum}
	err := datastore.Get(c, m.Key(c), m)
	if err != nil && err != datastore.ErrNoSuchEntity {
		return nil, fmt.Errorf("getting PerfMetricRun: %v", err)
	}
	if len(m.Vals) != PerfRunLength {
		m.Vals = make([]int64, PerfRunLength)
	}
	return m, nil
}

func (m *PerfMetricRun) AddMetric(c context.Context, commitNum int, v uint64) error {
	if commitNum < m.StartCommitNum || commitNum >= m.StartCommitNum+PerfRunLength {
		return fmt.Errorf("AddMetric: CommitNum %v out of range [%v, %v)",
			commitNum, m.StartCommitNum, m.StartCommitNum+PerfRunLength)
	}
	m.Vals[commitNum-m.StartCommitNum] = int64(v)
	if _, err := datastore.Put(c, m.Key(c), m); err != nil {
		return fmt.Errorf("putting PerfMetricRun: %v", err)
	}
	return nil
}

// GetPerfMetricsForCommits returns perf metrics for builder/benchmark/metric
// and commits [startCommitNum, startCommitNum+n).
func GetPerfMetricsForCommits(c context.Context, builder, benchmark, metric string, startCommitNum, n int) ([]uint64, error) {
	if startCommitNum < 0 || n <= 0 {
		return nil, fmt.Errorf("GetPerfMetricsForCommits: invalid args (%v, %v)", startCommitNum, n)
	}

	p := &Package{}
	t := datastore.NewQuery("PerfMetricRun").
		Ancestor(p.Key(c)).
		Filter("Builder =", builder).
		Filter("Benchmark =", benchmark).
		Filter("Metric =", metric).
		Filter("StartCommitNum >=", startCommitNum/PerfRunLength*PerfRunLength).
		Order("StartCommitNum").
		Limit(100).
		Run(c)

	res := make([]uint64, n)
	for {
		metrics := new(PerfMetricRun)
		_, err := t.Next(metrics)
		if err == datastore.Done {
			break
		}
		if err != nil {
			return nil, err
		}
		if metrics.StartCommitNum >= startCommitNum+n {
			break
		}
		// Calculate start index for copying.
		i := 0
		if metrics.StartCommitNum < startCommitNum {
			i = startCommitNum - metrics.StartCommitNum
		}
		// Calculate end index for copying.
		e := PerfRunLength
		if metrics.StartCommitNum+e > startCommitNum+n {
			e = startCommitNum + n - metrics.StartCommitNum
		}
		for ; i < e; i++ {
			res[metrics.StartCommitNum-startCommitNum+i] = uint64(metrics.Vals[i])
		}
		if e != PerfRunLength {
			break
		}
	}
	return res, nil
}

// PerfConfig holds read-mostly configuration related to benchmarking.
// There is only one PerfConfig entity.
type PerfConfig struct {
	BuilderBench []string `datastore:",noindex"` // "builder|benchmark" pairs
	BuilderProcs []string `datastore:",noindex"` // "builder|proc" pairs
	BenchMetric  []string `datastore:",noindex"` // "benchmark|metric" pairs
	NoiseLevels  []string `datastore:",noindex"` // "builder|benchmark|metric1=noise1|metric2=noise2"

	// Local cache of "builder|benchmark|metric" -> noise.
	noise map[string]float64
}

func PerfConfigKey(c context.Context) *datastore.Key {
	p := Package{}
	return datastore.NewKey(c, "PerfConfig", "PerfConfig", 0, p.Key(c))
}

const perfConfigCacheKey = "perf-config"

func GetPerfConfig(c context.Context, r *http.Request) (*PerfConfig, error) {
	pc := new(PerfConfig)
	now := cache.Now(c)
	if cache.Get(c, r, now, perfConfigCacheKey, pc) {
		return pc, nil
	}
	err := datastore.Get(c, PerfConfigKey(c), pc)
	if err != nil && err != datastore.ErrNoSuchEntity {
		return nil, fmt.Errorf("GetPerfConfig: %v", err)
	}
	cache.Set(c, r, now, perfConfigCacheKey, pc)
	return pc, nil
}

func (pc *PerfConfig) NoiseLevel(builder, benchmark, metric string) float64 {
	if pc.noise == nil {
		pc.noise = make(map[string]float64)
		for _, str := range pc.NoiseLevels {
			split := strings.Split(str, "|")
			builderBench := split[0] + "|" + split[1]
			for _, entry := range split[2:] {
				metricValue := strings.Split(entry, "=")
				noise, _ := strconv.ParseFloat(metricValue[1], 64)
				pc.noise[builderBench+"|"+metricValue[0]] = noise
			}
		}
	}
	me := fmt.Sprintf("%v|%v|%v", builder, benchmark, metric)
	n := pc.noise[me]
	if n == 0 {
		// Use a very conservative value
		// until we have learned the real noise level.
		n = 200
	}
	return n
}

// UpdatePerfConfig updates the PerfConfig entity with results of benchmarking.
// Returns whether it's a benchmark that we have not yet seem on the builder.
func UpdatePerfConfig(c context.Context, r *http.Request, req *PerfRequest) (newBenchmark bool, err error) {
	pc, err := GetPerfConfig(c, r)
	if err != nil {
		return false, err
	}

	modified := false
	add := func(arr *[]string, str string) {
		for _, s := range *arr {
			if s == str {
				return
			}
		}
		*arr = append(*arr, str)
		modified = true
		return
	}

	BenchProcs := strings.Split(req.Benchmark, "-")
	benchmark := BenchProcs[0]
	procs := "1"
	if len(BenchProcs) > 1 {
		procs = BenchProcs[1]
	}

	add(&pc.BuilderBench, req.Builder+"|"+benchmark)
	newBenchmark = modified
	add(&pc.BuilderProcs, req.Builder+"|"+procs)
	for _, m := range req.Metrics {
		add(&pc.BenchMetric, benchmark+"|"+m.Type)
	}

	if modified {
		if _, err := datastore.Put(c, PerfConfigKey(c), pc); err != nil {
			return false, fmt.Errorf("putting PerfConfig: %v", err)
		}
		cache.Tick(c)
	}
	return newBenchmark, nil
}

type MetricList []string

func (l MetricList) Len() int {
	return len(l)
}

func (l MetricList) Less(i, j int) bool {
	bi := strings.HasPrefix(l[i], "build-") || strings.HasPrefix(l[i], "binary-")
	bj := strings.HasPrefix(l[j], "build-") || strings.HasPrefix(l[j], "binary-")
	if bi == bj {
		return l[i] < l[j]
	}
	return !bi
}

func (l MetricList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

func collectList(all []string, idx int, second string) (res []string) {
	m := make(map[string]bool)
	for _, str := range all {
		ss := strings.Split(str, "|")
		v := ss[idx]
		v2 := ss[1-idx]
		if (second == "" || second == v2) && !m[v] {
			m[v] = true
			res = append(res, v)
		}
	}
	sort.Sort(MetricList(res))
	return res
}

func (pc *PerfConfig) BuildersForBenchmark(bench string) []string {
	return collectList(pc.BuilderBench, 0, bench)
}

func (pc *PerfConfig) BenchmarksForBuilder(builder string) []string {
	return collectList(pc.BuilderBench, 1, builder)
}

func (pc *PerfConfig) MetricsForBenchmark(bench string) []string {
	return collectList(pc.BenchMetric, 1, bench)
}

func (pc *PerfConfig) BenchmarkProcList() (res []string) {
	bl := pc.BenchmarksForBuilder("")
	pl := pc.ProcList("")
	for _, b := range bl {
		for _, p := range pl {
			res = append(res, fmt.Sprintf("%v-%v", b, p))
		}
	}
	return res
}

func (pc *PerfConfig) ProcList(builder string) []int {
	ss := collectList(pc.BuilderProcs, 1, builder)
	var procs []int
	for _, s := range ss {
		p, _ := strconv.ParseInt(s, 10, 32)
		procs = append(procs, int(p))
	}
	sort.Ints(procs)
	return procs
}

// A PerfTodo contains outstanding commits for benchmarking for a builder.
// Descendant of Package.
type PerfTodo struct {
	PackagePath string // (empty for main repo commits)
	Builder     string
	CommitNums  []int `datastore:",noindex"` // LIFO queue of commits to benchmark.
}

func (todo *PerfTodo) Key(c context.Context) *datastore.Key {
	p := Package{Path: todo.PackagePath}
	key := todo.Builder
	return datastore.NewKey(c, "PerfTodo", key, 0, p.Key(c))
}

// AddCommitToPerfTodo adds the commit to all existing PerfTodo entities.
func AddCommitToPerfTodo(c context.Context, com *Commit) error {
	var todos []*PerfTodo
	_, err := datastore.NewQuery("PerfTodo").
		Ancestor((&Package{}).Key(c)).
		GetAll(c, &todos)
	if err != nil {
		return fmt.Errorf("fetching PerfTodo's: %v", err)
	}
	for _, todo := range todos {
		todo.CommitNums = append(todo.CommitNums, com.Num)
		_, err = datastore.Put(c, todo.Key(c), todo)
		if err != nil {
			return fmt.Errorf("updating PerfTodo: %v", err)
		}
	}
	return nil
}

// A Log is a gzip-compressed log file stored under the SHA1 hash of the
// uncompressed log text.
type Log struct {
	CompressedLog []byte
}

func (l *Log) Text() ([]byte, error) {
	d, err := gzip.NewReader(bytes.NewBuffer(l.CompressedLog))
	if err != nil {
		return nil, fmt.Errorf("reading log data: %v", err)
	}
	b, err := ioutil.ReadAll(d)
	if err != nil {
		return nil, fmt.Errorf("reading log data: %v", err)
	}
	return b, nil
}

func PutLog(c context.Context, text string) (hash string, err error) {
	b := new(bytes.Buffer)
	z, _ := gzip.NewWriterLevel(b, gzip.BestCompression)
	io.WriteString(z, text)
	z.Close()
	hash = loghash.New(text)
	key := datastore.NewKey(c, "Log", hash, 0, nil)
	_, err = datastore.Put(c, key, &Log{b.Bytes()})
	return
}

// A Tag is used to keep track of the most recent Go weekly and release tags.
// Typically there will be one Tag entity for each kind of git tag.
type Tag struct {
	Kind string // "release", or "tip"
	Name string // the tag itself (for example: "release.r60")
	Hash string
}

func (t *Tag) String() string {
	if t.Kind == "tip" {
		return "tip"
	}
	return t.Name
}

func (t *Tag) Key(c context.Context) *datastore.Key {
	p := &Package{}
	s := t.Kind
	if t.Kind == "release" {
		s += "-" + t.Name
	}
	return datastore.NewKey(c, "Tag", s, 0, p.Key(c))
}

func (t *Tag) Valid() error {
	if t.Kind != "release" && t.Kind != "tip" {
		return errors.New("invalid Kind")
	}
	if t.Kind == "release" && t.Name == "" {
		return errors.New("release must have Name")
	}
	if !validHash(t.Hash) {
		return errors.New("invalid Hash")
	}
	return nil
}

// Commit returns the Commit that corresponds with this Tag.
func (t *Tag) Commit(c context.Context) (*Commit, error) {
	com := &Commit{Hash: t.Hash}
	err := datastore.Get(c, com.Key(c), com)
	return com, err
}

// GetTag fetches a Tag by name from the datastore.
func GetTag(c context.Context, kind, name string) (*Tag, error) {
	t := &Tag{Kind: kind, Name: name}
	if err := datastore.Get(c, t.Key(c), t); err != nil {
		return nil, err
	}
	if err := t.Valid(); err != nil {
		return nil, err
	}
	return t, nil
}

// Packages returns packages of the specified kind.
// Kind must be one of "external" or "subrepo".
func Packages(c context.Context, kind string) ([]*Package, error) {
	switch kind {
	case "external", "subrepo":
	default:
		return nil, errors.New(`kind must be one of "external" or "subrepo"`)
	}
	var pkgs []*Package
	q := datastore.NewQuery("Package").Filter("Kind=", kind)
	for t := q.Run(c); ; {
		pkg := new(Package)
		_, err := t.Next(pkg)
		if err == datastore.Done {
			break
		} else if err != nil {
			return nil, err
		}
		if pkg.Path != "" {
			pkgs = append(pkgs, pkg)
		}
	}
	return pkgs, nil
}
