// Copyright 2020 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 benchmark provides a Metrics object that enables memory and CPU
// profiling for the linker. The Metrics objects can be used to mark stages
// of the code, and name the measurements during that stage. There is also
// optional GCs that can be performed at the end of each stage, so you
// can get an accurate measurement of how each stage changes live memory.
package benchmark

import (
	"fmt"
	"io"
	"os"
	"runtime"
	"runtime/pprof"
	"time"
	"unicode"
)

type Flags int

const (
	GC         = 1 << iota
	NoGC Flags = 0
)

type Metrics struct {
	gc        Flags
	marks     []*mark
	curMark   *mark
	filebase  string
	pprofFile *os.File
}

type mark struct {
	name              string
	startM, endM, gcM runtime.MemStats
	startT, endT      time.Time
}

// New creates a new Metrics object.
//
// Typical usage should look like:
//
//	func main() {
//	  filename := "" // Set to enable per-phase pprof file output.
//	  bench := benchmark.New(benchmark.GC, filename)
//	  defer bench.Report(os.Stdout)
//	  // etc
//	  bench.Start("foo")
//	  foo()
//	  bench.Start("bar")
//	  bar()
//	}
//
// Note that a nil Metrics object won't cause any errors, so one could write
// code like:
//
//	func main() {
//	  enableBenchmarking := flag.Bool("enable", true, "enables benchmarking")
//	  flag.Parse()
//	  var bench *benchmark.Metrics
//	  if *enableBenchmarking {
//	    bench = benchmark.New(benchmark.GC)
//	  }
//	  bench.Start("foo")
//	  // etc.
//	}
func New(gc Flags, filebase string) *Metrics {
	if gc == GC {
		runtime.GC()
	}
	return &Metrics{gc: gc, filebase: filebase}
}

// Report reports the metrics.
// Closes the currently Start(ed) range, and writes the report to the given io.Writer.
func (m *Metrics) Report(w io.Writer) {
	if m == nil {
		return
	}

	m.closeMark()

	gcString := ""
	if m.gc == GC {
		gcString = "_GC"
	}

	var totTime time.Duration
	for _, curMark := range m.marks {
		dur := curMark.endT.Sub(curMark.startT)
		totTime += dur
		fmt.Fprintf(w, "%s 1 %d ns/op", makeBenchString(curMark.name+gcString), dur.Nanoseconds())
		fmt.Fprintf(w, "\t%d B/op", curMark.endM.TotalAlloc-curMark.startM.TotalAlloc)
		fmt.Fprintf(w, "\t%d allocs/op", curMark.endM.Mallocs-curMark.startM.Mallocs)
		if m.gc == GC {
			fmt.Fprintf(w, "\t%d live-B", curMark.gcM.HeapAlloc)
		} else {
			fmt.Fprintf(w, "\t%d heap-B", curMark.endM.HeapAlloc)
		}
		fmt.Fprintf(w, "\n")
	}
	fmt.Fprintf(w, "%s 1 %d ns/op\n", makeBenchString("total time"+gcString), totTime.Nanoseconds())
}

// Starts marks the beginning of a new measurement phase.
// Once a metric is started, it continues until either a Report is issued, or another Start is called.
func (m *Metrics) Start(name string) {
	if m == nil {
		return
	}
	m.closeMark()
	m.curMark = &mark{name: name}
	// Unlikely we need to a GC here, as one was likely just done in closeMark.
	if m.shouldPProf() {
		f, err := os.Create(makePProfFilename(m.filebase, name, "cpuprof"))
		if err != nil {
			panic(err)
		}
		m.pprofFile = f
		if err = pprof.StartCPUProfile(m.pprofFile); err != nil {
			panic(err)
		}
	}
	runtime.ReadMemStats(&m.curMark.startM)
	m.curMark.startT = time.Now()
}

func (m *Metrics) closeMark() {
	if m == nil || m.curMark == nil {
		return
	}
	m.curMark.endT = time.Now()
	if m.shouldPProf() {
		pprof.StopCPUProfile()
		m.pprofFile.Close()
		m.pprofFile = nil
	}
	runtime.ReadMemStats(&m.curMark.endM)
	if m.gc == GC {
		runtime.GC()
		runtime.ReadMemStats(&m.curMark.gcM)
		if m.shouldPProf() {
			// Collect a profile of the live heap. Do a
			// second GC to force sweep completion so we
			// get a complete snapshot of the live heap at
			// the end of this phase.
			runtime.GC()
			f, err := os.Create(makePProfFilename(m.filebase, m.curMark.name, "memprof"))
			if err != nil {
				panic(err)
			}
			err = pprof.WriteHeapProfile(f)
			if err != nil {
				panic(err)
			}
			err = f.Close()
			if err != nil {
				panic(err)
			}
		}
	}
	m.marks = append(m.marks, m.curMark)
	m.curMark = nil
}

// shouldPProf returns true if we should be doing pprof runs.
func (m *Metrics) shouldPProf() bool {
	return m != nil && len(m.filebase) > 0
}

// makeBenchString makes a benchmark string consumable by Go's benchmarking tools.
func makeBenchString(name string) string {
	needCap := true
	ret := []rune("Benchmark")
	for _, r := range name {
		if unicode.IsSpace(r) {
			needCap = true
			continue
		}
		if needCap {
			r = unicode.ToUpper(r)
			needCap = false
		}
		ret = append(ret, r)
	}
	return string(ret)
}

func makePProfFilename(filebase, name, typ string) string {
	return fmt.Sprintf("%s_%s.%s", filebase, makeBenchString(name), typ)
}
