package main

import (
	"context"
	"fmt"
	"os"
	"runtime"
	"runtime/trace"
	"time"
)

func work(ctx context.Context) int {
	ctx, task := trace.NewTask(ctx, "one-job")
	defer task.End()
	result := make(chan int)
	go func() {
		trace.WithRegion(ctx, "wait-input", func() { time.Sleep(20 * time.Millisecond) })
		trace.Log(ctx, "phase", "input-ready")
		total := 0
		trace.WithRegion(ctx, "compute", func() {
			for i := 0; i < 100000; i++ {
				total += i % 7
			}
		})
		result <- total
	}()
	var n int
	trace.WithRegion(ctx, "wait-result", func() { n = <-result })
	trace.WithRegion(ctx, "forced-gc", func() { runtime.GC() })
	return n
}
func run(path string) (err error) {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer func() {
		if e := f.Close(); err == nil {
			err = e
		}
	}()
	if err = trace.Start(f); err != nil {
		return err
	}
	defer trace.Stop()
	n := work(context.Background())
	if n != 299995 {
		return fmt.Errorf("bad result %d", n)
	}
	fmt.Println("result:", n)
	fmt.Println("trace enabled:", trace.IsEnabled())
	return nil
}
func main() {
	path := "trace.out"
	if len(os.Args) > 1 {
		path = os.Args[1]
	}
	if err := run(path); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
