// Copyright 2017 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Busybench is a tool that runs a benchmark with the profiler enabled.
package main

import (
	"bytes"
	"compress/gzip"
	"flag"
	"log"
	"math/rand"
	"runtime"
	"sync"
	"time"

	"cloud.google.com/go/profiler"
)

var (
	service        = flag.String("service", "", "service name")
	mutexProfiling = flag.Bool("mutex_profiling", false, "enable mutex profiling")
	duration       = flag.Int("duration", 150, "duration of the benchmark in seconds")
	apiAddr        = flag.String("api_address", "", "API address of the profiler (e.g. 'cloudprofiler.googleapis.com:443')")
	projectID      = flag.String("project_id", "", "cloud project ID")
)

// busywork continuously generates 1MiB of random data and compresses it
// throwing away the result.
func busywork(mu *sync.Mutex) {
	ticker := time.NewTicker(time.Duration(*duration) * time.Second)
	defer ticker.Stop()
	for {
		select {
		case <-ticker.C:
			return
		default:
			busyworkOnce(mu)
		}
	}
}

func busyworkOnce(mu *sync.Mutex) {
	data := make([]byte, 128*1024)
	rand.Read(data)

	// Grab the mutex after the allocation above is done so that
	// there are a number of outstanding allocations. This makes
	// the live heap profiles consistently non-empty.
	mu.Lock()
	defer mu.Unlock()
	var b bytes.Buffer
	gz := gzip.NewWriter(&b)
	if _, err := gz.Write(data); err != nil {
		log.Printf("Failed to write to gzip stream: %v", err)
		return
	}
	if err := gz.Flush(); err != nil {
		log.Printf("Failed to flush to gzip stream: %v", err)
		return
	}
	if err := gz.Close(); err != nil {
		log.Printf("Failed to close gzip stream: %v", err)
	}
	// Throw away the result.
}

func main() {
	flag.Parse()
	log.Printf("busybench using %s.", runtime.Version())
	defer log.Printf("busybench finished profiling.")

	if *service == "" {
		log.Print("Service name must be configured using --service flag.")
		return
	}
	if err := profiler.Start(profiler.Config{Service: *service,
		MutexProfiling: *mutexProfiling,
		DebugLogging:   true,
		APIAddr:        *apiAddr,
		ProjectID:      *projectID}); err != nil {
		log.Printf("Failed to start the profiler: %v", err)
		return
	}

	var mu sync.Mutex
	var wg sync.WaitGroup
	const numBusyworkers = 20
	wg.Add(numBusyworkers)
	runtime.GOMAXPROCS(numBusyworkers)

	for i := 0; i < numBusyworkers; i++ {
		go func() {
			defer wg.Done()
			busywork(&mu)
		}()
	}
	wg.Wait()
}
