package main

/*
Runs the frontend portion of the fuzzer.  This primarily is the webserver (see DESIGN.md)
*/

import (
	"encoding/base64"
	"encoding/json"
	"flag"
	"fmt"
	"html/template"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"

	"cloud.google.com/go/storage"
	"github.com/gorilla/mux"
	fcommon "go.skia.org/infra/fuzzer/go/common"
	"go.skia.org/infra/fuzzer/go/config"
	"go.skia.org/infra/fuzzer/go/data"
	"go.skia.org/infra/fuzzer/go/download_skia"
	"go.skia.org/infra/fuzzer/go/frontend"
	"go.skia.org/infra/fuzzer/go/frontend/fuzzcache"
	"go.skia.org/infra/fuzzer/go/frontend/fuzzpool"
	"go.skia.org/infra/fuzzer/go/frontend/gcsloader"
	"go.skia.org/infra/fuzzer/go/frontend/syncer"
	"go.skia.org/infra/fuzzer/go/issues"
	fstorage "go.skia.org/infra/fuzzer/go/storage"
	"go.skia.org/infra/fuzzer/go/version_watcher"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/fileutil"
	"go.skia.org/infra/go/gcs"
	"go.skia.org/infra/go/git/gitinfo"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/login"
	"go.skia.org/infra/go/skiaversion"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/go/vcsinfo"
	"golang.org/x/net/context"
	"google.golang.org/api/option"
)

const (
	// OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow.
	OAUTH2_CALLBACK_PATH = "/oauth2callback/"
)

var (
	// indexTemplate is the main index.html page we serve.
	indexTemplate *template.Template = nil
	// rollTemplate is used for /roll, which allows a user to roll the fuzzer forward.
	rollTemplate *template.Template = nil
	// detailsTemplate is used for /category, which displays the count of fuzzes in various files
	// as well as the stacktraces.
	detailsTemplate *template.Template = nil

	storageClient *storage.Client = nil

	versionWatcher *version_watcher.VersionWatcher = nil

	fuzzSyncer *syncer.FuzzSyncer = nil

	issueManager *issues.IssuesManager = nil

	fuzzPool *fuzzpool.FuzzPool = fuzzpool.New()

	repo     *gitinfo.GitInfo = nil
	repoLock sync.Mutex
)

var (
	// web server params
	host         = flag.String("host", "localhost", "HTTP service host")
	port         = flag.String("port", ":8001", "HTTP service port (e.g., ':8002')")
	local        = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	resourcesDir = flag.String("resources_dir", "", "The directory to find templates, JS, and CSS files. If blank the current directory will be used.")
	boltDBPath   = flag.String("bolt_db_path", "fuzzer-db", "The path to the bolt db to be used as a local cache.")
	promPort     = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")

	// OAUTH params
	authWhiteList = flag.String("auth_whitelist", login.DEFAULT_DOMAIN_WHITELIST, "White space separated list of domains and email addresses that are allowed to login.")
	redirectURL   = flag.String("redirect_url", "https://fuzzer.skia.org/oauth2callback/", "OAuth2 redirect url. Only used when local=false.")

	// Scanning params
	// At the moment, the front end does not actually build Skia.  It checks out Skia to get
	// commit information only.  However, it is still not a good idea to share SkiaRoot dirs.
	skiaRoot            = flag.String("skia_root", "", "[REQUIRED] The root directory of the Skia source code.  Cannot be safely shared with backend.")
	clangPath           = flag.String("clang_path", "", "[REQUIRED] The path to the clang executable.")
	clangPlusPlusPath   = flag.String("clang_p_p_path", "", "[REQUIRED] The path to the clang++ executable.")
	depotToolsPath      = flag.String("depot_tools_path", "", "The absolute path to depot_tools.  Can be empty if they are on your path.")
	executableCachePath = flag.String("executable_cache_path", filepath.Join(os.TempDir(), "executable_cache"), "The path in which built fuzz executables can be cached.  Can be safely shared with backend.")
	bucket              = flag.String("bucket", "skia-fuzzer", "The GCS bucket in which to locate found fuzzes.")
	downloadProcesses   = flag.Int("download_processes", 4, "The number of download processes to be used for fetching fuzzes.")

	// Other params
	versionCheckPeriod = flag.Duration("version_check_period", 20*time.Second, `The period used to check the version of Skia that needs fuzzing.`)
	fuzzSyncPeriod     = flag.Duration("fuzz_sync_period", 2*time.Minute, `The period used to sync bad fuzzes and check the count of grey and bad fuzzes.`)
	backendNames       = common.NewMultiStringFlag("backend_names", nil, "The names of all backend gce instances, e.g. skia-fuzzer-be-1")
)

var requiredFlags = []string{"skia_root", "clang_path", "clang_p_p_path", "bolt_db_path", "executable_cache_path"}

func Init() {
	reloadTemplates()
}

func reloadTemplates() {
	indexTemplate = template.Must(template.ParseFiles(
		filepath.Join(*resourcesDir, "templates/index.html"),
		filepath.Join(*resourcesDir, "templates/header.html"),
	))
	rollTemplate = template.Must(template.ParseFiles(
		filepath.Join(*resourcesDir, "templates/roll.html"),
		filepath.Join(*resourcesDir, "templates/header.html"),
	))
	detailsTemplate = template.New("details.html")
	// Allows this template to have Polymer binding in it and go template markup.  The go templates
	// have been changed to be {%.Thing%} instead of {{.Thing}}
	detailsTemplate.Delims("{%", "%}")
	detailsTemplate = template.Must(detailsTemplate.ParseFiles(
		filepath.Join(*resourcesDir, "templates/details.html"),
		filepath.Join(*resourcesDir, "templates/header.html"),
	))
}

func main() {
	defer common.LogPanic()
	// Calls flag.Parse()
	common.InitWithMust(
		"fuzzer-fe",
		common.PrometheusOpt(promPort),
		common.CloudLoggingOpt(),
	)

	if err := writeFlagsToConfig(); err != nil {
		sklog.Fatalf("Problem with configuration: %s", err)
	}

	Init()

	if err := setupOAuth(); err != nil {
		sklog.Fatal(err)
	}
	client := fstorage.NewFuzzerGCSClient(storageClient, config.GCS.Bucket)

	go func() {
		if err := download_skia.AtGCSRevision(client, config.Common.SkiaRoot, &config.Common, !*local); err != nil {
			sklog.Fatalf("Problem downloading Skia: %s", err)
		}

		fuzzSyncer = syncer.New(storageClient)
		fuzzSyncer.Start()

		cache, err := fuzzcache.New(config.FrontEnd.BoltDBPath)
		if err != nil {
			sklog.Fatalf("Could not create fuzz report cache at %s: %s", config.FrontEnd.BoltDBPath, err)
		}
		defer util.Close(cache)

		if err := gcsloader.LoadFromBoltDB(fuzzPool, cache); err != nil {
			sklog.Errorf("Could not load from boltdb.  Loading from source of truth anyway. %s", err)
		}
		gsLoader := gcsloader.New(storageClient, cache, fuzzPool)
		if err := gsLoader.LoadFreshFromGoogleStorage(); err != nil {
			sklog.Fatalf("Error loading in data from GCS: %s", err)
		}
		fuzzSyncer.SetGCSLoader(gsLoader)
		updater := frontend.NewVersionUpdater(gsLoader, fuzzSyncer)
		versionWatcher = version_watcher.New(client, config.Common.VersionCheckPeriod, nil, updater.HandleCurrentVersion)
		versionWatcher.Start()

		err = <-versionWatcher.Status
		sklog.Fatal(err)
	}()
	runServer()
}

func writeFlagsToConfig() error {
	// Check the required ones and terminate if they are not provided
	for _, f := range requiredFlags {
		if flag.Lookup(f).Value.String() == "" {
			return fmt.Errorf("Required flag %s is empty.", f)
		}
	}
	var err error
	config.Common.SkiaRoot, err = fileutil.EnsureDirExists(*skiaRoot)
	if err != nil {
		return err
	}
	config.Common.ExecutableCachePath, err = fileutil.EnsureDirExists(*executableCachePath)
	if err != nil {
		return err
	}
	config.FrontEnd.BoltDBPath = *boltDBPath
	config.Common.VersionCheckPeriod = *versionCheckPeriod
	config.Common.ClangPath = *clangPath
	config.Common.ClangPlusPlusPath = *clangPlusPlusPath
	config.Common.DepotToolsPath = *depotToolsPath

	config.GCS.Bucket = *bucket
	config.FrontEnd.NumDownloadProcesses = *downloadProcesses
	config.FrontEnd.FuzzSyncPeriod = *fuzzSyncPeriod
	config.FrontEnd.BackendNames = *backendNames
	return nil
}

func setupOAuth() error {
	useRedirectURL := fmt.Sprintf("http://localhost%s/oauth2callback/", *port)
	if !*local {
		useRedirectURL = *redirectURL
	}
	if err := login.Init(useRedirectURL, *authWhiteList); err != nil {
		return fmt.Errorf("Problem setting up server OAuth: %s", err)
	}

	client, err := auth.NewDefaultJWTServiceAccountClient(auth.SCOPE_READ_WRITE)
	if err != nil {
		return fmt.Errorf("Problem setting up client OAuth: %s", err)
	}

	storageClient, err = storage.NewClient(context.Background(), option.WithHTTPClient(client))
	if err != nil {
		return fmt.Errorf("Problem authenticating: %s", err)
	}

	issueManager = issues.NewManager(client)
	return nil
}

func runServer() {
	serverURL := "https://" + *host
	if *local {
		serverURL = "http://" + *host + *port
	}

	r := mux.NewRouter()
	r.PathPrefix("/res/").HandlerFunc(httputils.MakeResourceHandler(*resourcesDir))

	r.HandleFunc(OAUTH2_CALLBACK_PATH, login.OAuth2CallbackHandler)
	r.HandleFunc("/", indexHandler)
	r.HandleFunc("/category/{category:[0-9a-z_]+}", detailsPageHandler)
	r.HandleFunc("/category/{category:[0-9a-z_]+}/name/{name}", detailsPageHandler)
	r.HandleFunc("/category/{category:[0-9a-z_]+}/file/{file}", detailsPageHandler)
	r.HandleFunc("/category/{category:[0-9a-z_]+}/file/{file}/func/{function}", detailsPageHandler)
	r.HandleFunc(`/category/{category:[0-9a-z_]+}/file/{file}/func/{function}/line/{line}`, detailsPageHandler)
	r.HandleFunc("/loginstatus/", login.StatusHandler)
	r.HandleFunc("/logout/", login.LogoutHandler)
	r.HandleFunc("/json/version", skiaversion.JsonHandler)
	r.HandleFunc("/json/fuzz-summary", summaryJSONHandler)
	r.HandleFunc("/json/details", detailsJSONHandler)
	r.HandleFunc("/json/status", statusJSONHandler)
	r.HandleFunc(`/fuzz/{name:[0-9a-f]+}`, fuzzHandler)
	r.HandleFunc(`/metadata/{name:[0-9a-f]+_(?:debug|release)\.(?:err|dump|asan)}`, metadataHandler)
	r.HandleFunc("/newBug", newBugHandler)
	r.HandleFunc("/roll", rollHandler)
	r.HandleFunc("/roll/revision", updateRevision)

	rootHandler := login.ForceAuth(httputils.LoggingGzipRequestResponse(r), OAUTH2_CALLBACK_PATH)

	http.Handle("/", rootHandler)
	sklog.Infof("Ready to serve on %s", serverURL)
	sklog.Fatal(http.ListenAndServe(*port, nil))
}

// indexHandler displays the index page, which has no real templating. The client side JS will
// query for more information.
func indexHandler(w http.ResponseWriter, r *http.Request) {
	if *local {
		reloadTemplates()
	}
	w.Header().Set("Content-Type", "text/html")

	if err := indexTemplate.Execute(w, nil); err != nil {
		sklog.Errorf("Failed to expand template: %v", err)
	}
}

// detailsPageHandler displays the details page customized with the category requrested. The client
// side JS will query for more information.
func detailsPageHandler(w http.ResponseWriter, r *http.Request) {
	if *local {
		reloadTemplates()
	}
	w.Header().Set("Content-Type", "text/html")

	var cat = struct {
		Category string
	}{
		Category: mux.Vars(r)["category"],
	}

	if err := detailsTemplate.Execute(w, cat); err != nil {
		sklog.Errorf("Failed to expand template: %v", err)
	}
}

// rollHandler displays the roll page, which has no real templating. The client side JS will
// query for more information and post the roll.
func rollHandler(w http.ResponseWriter, r *http.Request) {
	if *local {
		reloadTemplates()
	}
	w.Header().Set("Content-Type", "text/html")

	if err := rollTemplate.Execute(w, nil); err != nil {
		sklog.Errorf("Failed to expand template: %v", err)
	}
}

// countSummary represents the data needed to summarize the results for a fuzzer, which is mostly
// counts of what has been found.
type countSummary struct {
	Category        string `json:"category"`
	CategoryDisplay string `json:"categoryDisplay"`
	TotalBad        int    `json:"totalBadCount"`
	TotalGrey       int    `json:"totalGreyCount"`
	// "This" means "newly introduced/fixed in this revision"
	ThisBad        int    `json:"thisBadCount"`
	ThisRegression int    `json:"thisRegressionCount"`
	Status         string `json:"status"`
	Groomer        string `json:"groomer"`
}

// summaryJSONHandler returns a countSummary, representing the results for all fuzzers.
func summaryJSONHandler(w http.ResponseWriter, r *http.Request) {
	summary := getSummary()
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(summary); err != nil {
		sklog.Errorf("Failed to write or encode output: %v", err)
		return
	}
}

// getSummary() creates a countSummary for every fuzzer.
func getSummary() []countSummary {
	counts := make([]countSummary, 0, len(fcommon.FUZZ_CATEGORIES))
	for _, cat := range fcommon.FUZZ_CATEGORIES {
		o := countSummary{
			CategoryDisplay: fcommon.PrettifyCategory(cat),
			Category:        cat,
		}
		c := syncer.FuzzCount{
			TotalBad:       -1,
			TotalGrey:      -1,
			ThisBad:        -1,
			ThisRegression: -1,
		}
		if fuzzSyncer != nil {
			c = fuzzSyncer.LastCount(cat)
		}
		o.TotalBad = c.TotalBad
		o.ThisBad = c.ThisBad
		o.TotalGrey = c.TotalGrey
		o.ThisRegression = c.ThisRegression
		o.Status = fcommon.Status(cat)
		o.Groomer = fcommon.Groomer(cat)
		counts = append(counts, o)
	}
	return counts
}

// detailsJSONHandler returns the "details" for a given fuzzer, optionally filtered by file name,
// function name and line number.
func detailsJSONHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	category := r.FormValue("category")
	architecture := r.FormValue("architecture")
	name := r.FormValue("name")
	badOrGrey := r.FormValue("badOrGrey")

	// The file names have "/" in them and the functions can have "(*&" in them.
	// We base64 encode them to prevent problems.
	file, err := decodeBase64(r.FormValue("file"))
	if err != nil {
		httputils.ReportError(w, r, err, "There was a problem decoding the params.")
		return
	}
	function, err := decodeBase64(r.FormValue("func"))
	if err != nil {
		httputils.ReportError(w, r, err, "There was a problem decoding the params.")
		return
	}
	lineStr, err := decodeBase64(r.FormValue("line"))
	if err != nil {
		httputils.ReportError(w, r, err, "There was a problem decoding the params.")
		return
	}

	var reports []data.FuzzReport
	if name != "" {
		if report, err := fuzzPool.FindFuzzDetailForFuzz(name); err != nil {
			httputils.ReportError(w, r, err, "There was a problem fulfilling the request.")
		} else {
			reports = append(reports, report)
		}
	} else {
		line, err := strconv.ParseInt(lineStr, 10, 32)
		if err != nil {
			line = fcommon.UNKNOWN_LINE
		}
		if badOrGrey != "grey" && badOrGrey != "bad" {
			badOrGrey = ""
		}

		if reports, err = fuzzPool.FindFuzzDetails(category, architecture, badOrGrey, file, function, int(line)); err != nil {
			httputils.ReportError(w, r, err, "There was a problem fulfilling the request.")
			return
		}
	}

	if err := json.NewEncoder(w).Encode(reports); err != nil {
		sklog.Errorf("Failed to write or encode output: %s", err)
		return
	}
}

func decodeBase64(s string) (string, error) {
	if s == "" {
		return "", nil
	}
	b, err := base64.URLEncoding.DecodeString(s)
	return string(b), err
}

// fuzzHandler serves the contents of the fuzz as application/octet-stream.  It looks up the fuzz
// by name in the fuzzPool and uses the category/architecture/badness from the returned FuzzReport
// to fetch it from Google Storage and return it to the user.  This primarily allows users to
// download grey fuzzes if they want to and simplifies the client side request.
func fuzzHandler(w http.ResponseWriter, r *http.Request) {
	v := mux.Vars(r)

	name := v["name"]
	if fuzzPool == nil {
		httputils.ReportError(w, r, nil, "Fuzzes not loaded yet")
		return
	}
	fuzz, err := fuzzPool.FindFuzzDetailForFuzz(name)
	if err != nil {
		httputils.ReportError(w, r, err, "Fuzz not found")
		return
	}
	badOrGrey := "bad"
	if fuzz.IsGrey {
		badOrGrey = "grey"
	}

	contents, err := gcs.FileContentsFromGCS(storageClient, config.GCS.Bucket, fmt.Sprintf("%s/%s/%s/%s/%s/%s", fuzz.FuzzCategory, config.Common.SkiaVersion.Hash, fuzz.FuzzArchitecture, badOrGrey, fuzz.FuzzName, fuzz.FuzzName))
	if err != nil {
		httputils.ReportError(w, r, err, "Fuzz not found")
		return
	}
	w.Header().Set("Content-Type", "application/octet-stream")
	w.Header().Set("Content-Disposition", name)
	n, err := w.Write(contents)
	if err != nil || n != len(contents) {
		sklog.Errorf("Could only serve %d bytes of fuzz %s, not %d: %s", n, name, len(contents), err)
		return
	}
}

// metadataHandler serves the contents of a fuzz's metadata (e.g. stacktrace) as text/plain
//  It looks up the fuzz by name in the fuzzPool and uses the category/architecture/badness from
// the returned FuzzReport to fetch the metadata from Google Storage and return it to the user.
// This primarily allows users to download grey fuzz metadata if they want to and simplifies
//  the client side request.
func metadataHandler(w http.ResponseWriter, r *http.Request) {
	v := mux.Vars(r)
	name := v["name"]
	hash := strings.Split(name, "_")[0]
	if fuzzPool == nil {
		httputils.ReportError(w, r, nil, "Fuzzes not loaded yet")
		return
	}
	fuzz, err := fuzzPool.FindFuzzDetailForFuzz(hash)
	if err != nil {
		httputils.ReportError(w, r, err, "Fuzz not found")
		return
	}
	badOrGrey := "bad"
	if fuzz.IsGrey {
		badOrGrey = "grey"
	}

	contents, err := gcs.FileContentsFromGCS(storageClient, config.GCS.Bucket, fmt.Sprintf("%s/%s/%s/%s/%s/%s", fuzz.FuzzCategory, config.Common.SkiaVersion.Hash, fuzz.FuzzArchitecture, badOrGrey, fuzz.FuzzName, name))
	if err != nil {
		httputils.ReportError(w, r, err, "Fuzz metadata not found")
		return
	}
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.Header().Set("Content-Disposition", name)
	n, err := w.Write(contents)
	if err != nil || n != len(contents) {
		sklog.Errorf("Could only serve %d bytes of metadata %s, not %d: %s", n, name, len(contents), err)
		return
	}
}

type commit struct {
	Hash   string `json:"hash"`
	Author string `json:"author"`
}

// The status struct indicates what Skia revision the fuzzer is currently working on and if it
// is in the middle of rolling to a new revision.
type status struct {
	Current     commit    `json:"current"`
	Pending     *commit   `json:"pending"`
	LastUpdated time.Time `json:"lastUpdated"`
}

// statusJSONHandler returns the current status of the fuzzer using information from the config
// and versionwatcher.  TODO(kjlubick): should it use the config or just versionWatcher?
func statusJSONHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	s := status{
		Current: commit{
			Hash:   "loading",
			Author: "(Loading)",
		},
		Pending: nil,
	}

	if config.Common.SkiaVersion != nil {
		s.Current.Hash = config.Common.SkiaVersion.Hash
		s.Current.Author = config.Common.SkiaVersion.Author
		s.LastUpdated = config.Common.SkiaVersion.Timestamp
		if versionWatcher != nil {
			if pending := versionWatcher.LastPendingHash; pending != "" {
				if ci, err := getCommitInfo(pending); err != nil {
					sklog.Errorf("Problem getting git info about pending revision %s: %s", pending, err)
				} else {
					s.Pending = &commit{
						Hash:   ci.Hash,
						Author: ci.Author,
					}
				}
			}
		}
	}

	if err := json.NewEncoder(w).Encode(s); err != nil {
		sklog.Errorf("Failed to write or encode output: %s", err)
		return
	}
}

// newBugHandler redirects the request to a pre-filled bug report at Monorail.
func newBugHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	name := r.FormValue("name")
	category := r.FormValue("category")

	p := issues.IssueReportingPackage{
		Category:       category,
		FuzzName:       name,
		CommitRevision: config.Common.SkiaVersion.Hash,
	}
	if u, err := issueManager.CreateBadBugURL(p); err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Problem creating issue link %#v", p))
	} else {
		// 303 means "make a GET request to this url"
		http.Redirect(w, r, u, 303)
	}
}

// getCommitInfo updates the front end's checkout of Skia and then queries it for information about the given revision.
func getCommitInfo(revision string) (*vcsinfo.LongCommit, error) {
	repoLock.Lock()
	defer repoLock.Unlock()
	var err error
	repo, err = gitinfo.NewGitInfo(filepath.Join(config.Common.SkiaRoot, "skia"), false, false)
	if err != nil {
		return nil, fmt.Errorf("Could not create Skia repo: %s", err)
	}

	if err = repo.Checkout("master"); err != nil {
		return nil, fmt.Errorf("Could not checkout master: %s", err)
	}

	if err = repo.Update(true, false); err != nil {
		return nil, fmt.Errorf("Could not update master branch: %s", err)
	}

	currInfo, err := repo.Details(revision, false)
	if err != nil || currInfo == nil {
		return nil, fmt.Errorf("Could not get info for %s: %s", revision, err)
	}
	return currInfo, nil
}

// updateRevision handles the POST request to roll the revision under fuzz forward.  It checks for
// authentication, verifies the revision is legit, that we are not already rolling forward,
// and then updates GCS with a pending version.
func updateRevision(w http.ResponseWriter, r *http.Request) {
	if !login.IsGoogler(r) {
		http.Error(w, "You do not have permission to push.  You must be a Googler.", http.StatusForbidden)
		return
	}
	var msg struct {
		Revision string `json:"revision"`
	}
	if err := json.NewDecoder(r.Body).Decode(&msg); err != nil {
		httputils.ReportError(w, r, err, fmt.Sprintf("Failed to decode request body: %s", err))
		return
	}
	msg.Revision = strings.TrimSpace(msg.Revision)
	if msg.Revision == "" {
		http.Error(w, "Revision cannot be blank", http.StatusBadRequest)
		return
	}
	user := login.LoggedInAs(r)

	sklog.Infof("User %s is trying to roll the fuzzer to revision %q", user, msg.Revision)

	if config.Common.SkiaVersion == nil || versionWatcher == nil || versionWatcher.LastCurrentHash == "" {
		http.Error(w, "The fuzzer isn't finished booting up.  Try again later.", http.StatusServiceUnavailable)
		return
	}
	if versionWatcher.LastPendingHash != "" {
		http.Error(w, "There is already a pending version.", http.StatusBadRequest)
		return
	}

	currInfo, err := getCommitInfo(versionWatcher.LastCurrentHash)
	if err != nil || currInfo == nil {
		httputils.ReportError(w, r, err, "Could not get information about current revision.  Please try again later")
		return
	}
	newInfo, err := getCommitInfo(msg.Revision)
	if err != nil || newInfo == nil {
		httputils.ReportError(w, r, err, "Could not get information about revision.  Are you sure it exists?")
		return
	}

	// We can only assume this to be the case because Skia has no branches that would
	// cause commits of a later time to actually be merged in before other commits.
	if newInfo.Timestamp.Before(currInfo.Timestamp) {
		http.Error(w, fmt.Sprintf("Revision cannot be before current revision %s at %s", currInfo.Hash, currInfo.Timestamp), http.StatusBadRequest)
		return
	}

	client := fstorage.NewFuzzerGCSClient(storageClient, config.GCS.Bucket)

	sklog.Infof("Turning the crank to revision %q", newInfo.Hash)
	if err := frontend.UpdateVersionToFuzz(client, config.FrontEnd.BackendNames, newInfo.Hash); err != nil {
		sklog.Errorf("Could not turn the crank: %s", err)
	} else {
		versionWatcher.Recheck()
	}
}
