package main

import (
	"fmt"
	"github.com/felixge/fgprof"
	"net/http"
	"os"
	"runtime/pprof"
	"runtime/trace"
	"time"
)

var value uint64

//go:noinline
func calculate() {
	until := time.Now().Add(60 * time.Millisecond)
	x := uint64(1)
	for time.Now().Before(until) {
		for range 10000 {
			x = x*1664525 + 1013904223
		}
	}
	value = x
}

//go:noinline
func waitIO() { time.Sleep(120 * time.Millisecond) }
func run(mode, path string) error {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	var stop func() error
	switch mode {
	case "fgprof":
		stop = fgprof.Start(f, fgprof.FormatPprof)
	case "cpu":
		if err := pprof.StartCPUProfile(f); err != nil {
			f.Close()
			return err
		}
		stop = func() error { pprof.StopCPUProfile(); return nil }
	case "trace":
		if err := trace.Start(f); err != nil {
			f.Close()
			return err
		}
		stop = func() error { trace.Stop(); return nil }
	default:
		f.Close()
		return fmt.Errorf("unknown mode %q", mode)
	}
	for range 2 {
		waitIO()
		calculate()
	}
	err = stop()
	closeErr := f.Close()
	if err != nil {
		return err
	}
	if closeErr != nil {
		return closeErr
	}
	fmt.Println(mode, "capture complete")
	return nil
}
func main() {
	if len(os.Args) != 3 {
		fmt.Fprintln(os.Stderr, "usage: lab fgprof|cpu|trace output")
		os.Exit(2)
	}
	if err := run(os.Args[1], os.Args[2]); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func diagnosticsMux() *http.ServeMux {
	m := http.NewServeMux()
	m.Handle("GET /debug/fgprof", fgprof.Handler())
	return m
}
