// 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 (
	"encoding/json"
	"fmt"
	"net/http"

	"context"

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

func updateBenchmark(w http.ResponseWriter, r *http.Request) {
	if !appengine.IsDevAppServer() {
		fmt.Fprint(w, "Update must not run on real server.")
		return
	}

	if r.Method != "POST" {
		fmt.Fprintf(w, "bad request method")
		return
	}

	c := contextForRequest(r)
	if !validKey(c, r.FormValue("key"), r.FormValue("builder")) {
		fmt.Fprintf(w, "bad builder/key")
		return
	}

	defer r.Body.Close()
	var hashes []string
	if err := json.NewDecoder(r.Body).Decode(&hashes); err != nil {
		fmt.Fprintf(w, "failed to decode request: %v", err)
		return
	}

	ncommit := 0
	nrun := 0
	tx := func(c context.Context) error {
		var cr *CommitRun
		for _, hash := range hashes {
			// Update Commit.
			com := &Commit{Hash: hash}
			err := datastore.Get(c, com.Key(c), com)
			if err != nil && err != datastore.ErrNoSuchEntity {
				return fmt.Errorf("fetching Commit: %v", err)
			}
			if err == datastore.ErrNoSuchEntity {
				continue
			}
			com.NeedsBenchmarking = true
			com.PerfResults = nil
			if err := putCommit(c, com); err != nil {
				return err
			}
			ncommit++

			// create PerfResult
			res := &PerfResult{CommitHash: com.Hash, CommitNum: com.Num}
			err = datastore.Get(c, res.Key(c), res)
			if err != nil && err != datastore.ErrNoSuchEntity {
				return fmt.Errorf("fetching PerfResult: %v", err)
			}
			if err == datastore.ErrNoSuchEntity {
				if _, err := datastore.Put(c, res.Key(c), res); err != nil {
					return fmt.Errorf("putting PerfResult: %v", err)
				}
			}

			// Update CommitRun.
			if cr != nil && cr.StartCommitNum != com.Num/PerfRunLength*PerfRunLength {
				if _, err := datastore.Put(c, cr.Key(c), cr); err != nil {
					return fmt.Errorf("putting CommitRun: %v", err)
				}
				nrun++
				cr = nil
			}
			if cr == nil {
				var err error
				cr, err = GetCommitRun(c, com.Num)
				if err != nil {
					return fmt.Errorf("getting CommitRun: %v", err)
				}
			}
			if com.Num < cr.StartCommitNum || com.Num >= cr.StartCommitNum+PerfRunLength {
				return fmt.Errorf("commit num %v out of range [%v, %v)", com.Num, cr.StartCommitNum, cr.StartCommitNum+PerfRunLength)
			}
			idx := com.Num - cr.StartCommitNum
			cr.Hash[idx] = com.Hash
			cr.User[idx] = shortDesc(com.User)
			cr.Desc[idx] = shortDesc(com.Desc)
			cr.Time[idx] = com.Time
			cr.NeedsBenchmarking[idx] = com.NeedsBenchmarking
		}
		if cr != nil {
			if _, err := datastore.Put(c, cr.Key(c), cr); err != nil {
				return fmt.Errorf("putting CommitRun: %v", err)
			}
			nrun++
		}
		return nil
	}
	if err := datastore.RunInTransaction(c, tx, nil); err != nil {
		fmt.Fprintf(w, "failed to execute tx: %v", err)
		return
	}
	fmt.Fprintf(w, "OK (updated %v commits and %v commit runs)", ncommit, nrun)
}
