// LoadBinaryFuzzesFromGoogleStorage pulls all fuzzes out of GCS that are on the given whitelist
// and loads them into memory (as staging).  After loading them, it updates the cache
// and moves them from staging to the current copy.
func (g *GSLoader) LoadBinaryFuzzesFromGoogleStorage(whitelist []string) error {
	revision := config.FrontEnd.SkiaVersion.Hash
	sort.Strings(whitelist)
	reports, err := g.getBinaryReportsFromGS(fmt.Sprintf("binary_fuzzes/%s/bad/", revision), whitelist)
	if err != nil {
		return err
	}
	fuzz.StagingFromCurrent()
	n := 0
	for report := range reports {
		if g.finder != nil {
			report.DebugStackTrace.LookUpFunctions(g.finder)
			report.ReleaseStackTrace.LookUpFunctions(g.finder)
		}
		fuzz.NewBinaryFuzzFound(report)
		n++
	}
	glog.Infof("%d new fuzzes loaded from Google Storage", n)
	fuzz.StagingToCurrent()

	_, oldBinaryFuzzNames, err := g.Cache.Load(revision)
	if err != nil {
		glog.Warningf("Could not read old binary fuzz names from cache.  Continuing...", err)
		oldBinaryFuzzNames = []string{}
	}

	return g.Cache.Store(fuzz.StagingCopy(), append(oldBinaryFuzzNames, whitelist...), revision)
}
// LoadFromBoltDB loads the fuzz.FuzzReport from FuzzReportCache associated with the given hash.
// The FuzzReport is first put into the staging fuzz cache, and then into the current.
// If a cache for the commit does not exist, or there are other problems with the retrieval,
// an error is returned.
func LoadFromBoltDB(cache *fuzzcache.FuzzReportCache) error {
	glog.Infof("Looking into cache for revision %s", config.FrontEnd.SkiaVersion.Hash)
	if staging, fuzzes, err := cache.Load(config.FrontEnd.SkiaVersion.Hash); err != nil {
		return fmt.Errorf("Problem decoding existing from bolt db: %s", err)
	} else {
		fuzz.SetStaging(*staging)
		fuzz.StagingToCurrent()
		glog.Infof("Successfully loaded %d binary fuzzes from bolt db cache", len(fuzzes))
	}
	return nil
}
// LoadFreshFromGoogleStorage pulls all fuzzes out of GCS and loads them into memory.
// The "fresh" in the name refers to the fact that all other loaded fuzzes (if any)
// are written over, including in the cache.
// Upon completion, the full results are cached to a boltDB instance and moved from staging
// to the current copy.
func (g *GSLoader) LoadFreshFromGoogleStorage() error {
	revision := config.FrontEnd.SkiaVersion.Hash
	reports, err := g.getBinaryReportsFromGS(fmt.Sprintf("binary_fuzzes/%s/bad/", revision), nil)
	if err != nil {
		return err
	}
	fuzz.ClearStaging()
	binaryFuzzNames := make([]string, 0, len(reports))
	for report := range reports {
		report.DebugStackTrace.LookUpFunctions(g.finder)
		report.ReleaseStackTrace.LookUpFunctions(g.finder)
		fuzz.NewBinaryFuzzFound(report)
		binaryFuzzNames = append(binaryFuzzNames, report.BadBinaryName)
	}
	glog.Infof("%d fuzzes freshly loaded from Google Storage", len(binaryFuzzNames))
	fuzz.StagingToCurrent()

	return g.Cache.Store(fuzz.StagingCopy(), binaryFuzzNames, revision)
}