// Copyright 2015 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 trace implements tracing of requests and long-lived objects.
It exports HTTP interfaces on /debug/requests and /debug/events.

A trace.Trace provides tracing for short-lived objects, usually requests.
A request handler might be implemented like this:

	func fooHandler(w http.ResponseWriter, req *http.Request) {
		tr := trace.New("mypkg.Foo", req.URL.Path)
		defer tr.Finish()
		...
		tr.LazyPrintf("some event %q happened", str)
		...
		if err := somethingImportant(); err != nil {
			tr.LazyPrintf("somethingImportant failed: %v", err)
			tr.SetError()
		}
	}

The /debug/requests HTTP endpoint organizes the traces by family,
errors, and duration.  It also provides histogram of request duration
for each family.

A trace.EventLog provides tracing for long-lived objects, such as RPC
connections.

	// A Fetcher fetches URL paths for a single domain.
	type Fetcher struct {
		domain string
		events trace.EventLog
	}

	func NewFetcher(domain string) *Fetcher {
		return &Fetcher{
			domain,
			trace.NewEventLog("mypkg.Fetcher", domain),
		}
	}

	func (f *Fetcher) Fetch(path string) (string, error) {
		resp, err := http.Get("http://" + f.domain + "/" + path)
		if err != nil {
			f.events.Errorf("Get(%q) = %v", path, err)
			return "", err
		}
		f.events.Printf("Get(%q) = %s", path, resp.Status)
		...
	}

	func (f *Fetcher) Close() error {
		f.events.Finish()
		return nil
	}

The /debug/events HTTP endpoint organizes the event logs by family and
by time since the last error.  The expanded view displays recent log
entries and the log's call stack.
*/
package trace // import "golang.org/x/net/trace"

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"log"
	"net"
	"net/http"
	"runtime"
	"sort"
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/net/context"
	"golang.org/x/net/internal/timeseries"
)

// DebugUseAfterFinish controls whether to debug uses of Trace values after finishing.
// FOR DEBUGGING ONLY. This will slow down the program.
var DebugUseAfterFinish = false

// AuthRequest determines whether a specific request is permitted to load the
// /debug/requests or /debug/events pages.
//
// It returns two bools; the first indicates whether the page may be viewed at all,
// and the second indicates whether sensitive events will be shown.
//
// AuthRequest may be replaced by a program to customise its authorisation requirements.
//
// The default AuthRequest function returns (true, true) iff the request comes from localhost/127.0.0.1/[::1].
var AuthRequest = func(req *http.Request) (any, sensitive bool) {
	// RemoteAddr is commonly in the form "IP" or "IP:port".
	// If it is in the form "IP:port", split off the port.
	host, _, err := net.SplitHostPort(req.RemoteAddr)
	if err != nil {
		host = req.RemoteAddr
	}
	switch host {
	case "localhost", "127.0.0.1", "::1":
		return true, true
	default:
		return false, false
	}
}

func init() {
	http.HandleFunc("/debug/requests", func(w http.ResponseWriter, req *http.Request) {
		any, sensitive := AuthRequest(req)
		if !any {
			http.Error(w, "not allowed", http.StatusUnauthorized)
			return
		}
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		Render(w, req, sensitive)
	})
	http.HandleFunc("/debug/events", func(w http.ResponseWriter, req *http.Request) {
		any, sensitive := AuthRequest(req)
		if !any {
			http.Error(w, "not allowed", http.StatusUnauthorized)
			return
		}
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		RenderEvents(w, req, sensitive)
	})
}

// Render renders the HTML page typically served at /debug/requests.
// It does not do any auth checking; see AuthRequest for the default auth check
// used by the handler registered on http.DefaultServeMux.
// req may be nil.
func Render(w io.Writer, req *http.Request, sensitive bool) {
	data := &struct {
		Families         []string
		ActiveTraceCount map[string]int
		CompletedTraces  map[string]*family

		// Set when a bucket has been selected.
		Traces        traceList
		Family        string
		Bucket        int
		Expanded      bool
		Traced        bool
		Active        bool
		ShowSensitive bool // whether to show sensitive events

		Histogram       template.HTML
		HistogramWindow string // e.g. "last minute", "last hour", "all time"

		// If non-zero, the set of traces is a partial set,
		// and this is the total number.
		Total int
	}{
		CompletedTraces: completedTraces,
	}

	data.ShowSensitive = sensitive
	if req != nil {
		// Allow show_sensitive=0 to force hiding of sensitive data for testing.
		// This only goes one way; you can't use show_sensitive=1 to see things.
		if req.FormValue("show_sensitive") == "0" {
			data.ShowSensitive = false
		}

		if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
			data.Expanded = exp
		}
		if exp, err := strconv.ParseBool(req.FormValue("rtraced")); err == nil {
			data.Traced = exp
		}
	}

	completedMu.RLock()
	data.Families = make([]string, 0, len(completedTraces))
	for fam := range completedTraces {
		data.Families = append(data.Families, fam)
	}
	completedMu.RUnlock()
	sort.Strings(data.Families)

	// We are careful here to minimize the time spent locking activeMu,
	// since that lock is required every time an RPC starts and finishes.
	data.ActiveTraceCount = make(map[string]int, len(data.Families))
	activeMu.RLock()
	for fam, s := range activeTraces {
		data.ActiveTraceCount[fam] = s.Len()
	}
	activeMu.RUnlock()

	var ok bool
	data.Family, data.Bucket, ok = parseArgs(req)
	switch {
	case !ok:
		// No-op
	case data.Bucket == -1:
		data.Active = true
		n := data.ActiveTraceCount[data.Family]
		data.Traces = getActiveTraces(data.Family)
		if len(data.Traces) < n {
			data.Total = n
		}
	case data.Bucket < bucketsPerFamily:
		if b := lookupBucket(data.Family, data.Bucket); b != nil {
			data.Traces = b.Copy(data.Traced)
		}
	default:
		if f := getFamily(data.Family, false); f != nil {
			var obs timeseries.Observable
			f.LatencyMu.RLock()
			switch o := data.Bucket - bucketsPerFamily; o {
			case 0:
				obs = f.Latency.Minute()
				data.HistogramWindow = "last minute"
			case 1:
				obs = f.Latency.Hour()
				data.HistogramWindow = "last hour"
			case 2:
				obs = f.Latency.Total()
				data.HistogramWindow = "all time"
			}
			f.LatencyMu.RUnlock()
			if obs != nil {
				data.Histogram = obs.(*histogram).html()
			}
		}
	}

	if data.Traces != nil {
		defer data.Traces.Free()
		sort.Sort(data.Traces)
	}

	completedMu.RLock()
	defer completedMu.RUnlock()
	if err := pageTmpl.ExecuteTemplate(w, "Page", data); err != nil {
		log.Printf("net/trace: Failed executing template: %v", err)
	}
}

func parseArgs(req *http.Request) (fam string, b int, ok bool) {
	if req == nil {
		return "", 0, false
	}
	fam, bStr := req.FormValue("fam"), req.FormValue("b")
	if fam == "" || bStr == "" {
		return "", 0, false
	}
	b, err := strconv.Atoi(bStr)
	if err != nil || b < -1 {
		return "", 0, false
	}

	return fam, b, true
}

func lookupBucket(fam string, b int) *traceBucket {
	f := getFamily(fam, false)
	if f == nil || b < 0 || b >= len(f.Buckets) {
		return nil
	}
	return f.Buckets[b]
}

type contextKeyT string

var contextKey = contextKeyT("golang.org/x/net/trace.Trace")

// NewContext returns a copy of the parent context
// and associates it with a Trace.
func NewContext(ctx context.Context, tr Trace) context.Context {
	return context.WithValue(ctx, contextKey, tr)
}

// FromContext returns the Trace bound to the context, if any.
func FromContext(ctx context.Context) (tr Trace, ok bool) {
	tr, ok = ctx.Value(contextKey).(Trace)
	return
}

// Trace represents an active request.
type Trace interface {
	// LazyLog adds x to the event log. It will be evaluated each time the
	// /debug/requests page is rendered. Any memory referenced by x will be
	// pinned until the trace is finished and later discarded.
	LazyLog(x fmt.Stringer, sensitive bool)

	// LazyPrintf evaluates its arguments with fmt.Sprintf each time the
	// /debug/requests page is rendered. Any memory referenced by a will be
	// pinned until the trace is finished and later discarded.
	LazyPrintf(format string, a ...interface{})

	// SetError declares that this trace resulted in an error.
	SetError()

	// SetRecycler sets a recycler for the trace.
	// f will be called for each event passed to LazyLog at a time when
	// it is no longer required, whether while the trace is still active
	// and the event is discarded, or when a completed trace is discarded.
	SetRecycler(f func(interface{}))

	// SetTraceInfo sets the trace info for the trace.
	// This is currently unused.
	SetTraceInfo(traceID, spanID uint64)

	// SetMaxEvents sets the maximum number of events that will be stored
	// in the trace. This has no effect if any events have already been
	// added to the trace.
	SetMaxEvents(m int)

	// Finish declares that this trace is complete.
	// The trace should not be used after calling this method.
	Finish()
}

type lazySprintf struct {
	format string
	a      []interface{}
}

func (l *lazySprintf) String() string {
	return fmt.Sprintf(l.format, l.a...)
}

// New returns a new Trace with the specified family and title.
func New(family, title string) Trace {
	tr := newTrace()
	tr.ref()
	tr.Family, tr.Title = family, title
	tr.Start = time.Now()
	tr.events = make([]event, 0, maxEventsPerTrace)

	activeMu.RLock()
	s := activeTraces[tr.Family]
	activeMu.RUnlock()
	if s == nil {
		activeMu.Lock()
		s = activeTraces[tr.Family] // check again
		if s == nil {
			s = new(traceSet)
			activeTraces[tr.Family] = s
		}
		activeMu.Unlock()
	}
	s.Add(tr)

	// Trigger allocation of the completed trace structure for this family.
	// This will cause the family to be present in the request page during
	// the first trace of this family. We don't care about the return value,
	// nor is there any need for this to run inline, so we execute it in its
	// own goroutine, but only if the family isn't allocated yet.
	completedMu.RLock()
	if _, ok := completedTraces[tr.Family]; !ok {
		go allocFamily(tr.Family)
	}
	completedMu.RUnlock()

	return tr
}

func (tr *trace) Finish() {
	tr.Elapsed = time.Now().Sub(tr.Start)
	if DebugUseAfterFinish {
		buf := make([]byte, 4<<10) // 4 KB should be enough
		n := runtime.Stack(buf, false)
		tr.finishStack = buf[:n]
	}

	activeMu.RLock()
	m := activeTraces[tr.Family]
	activeMu.RUnlock()
	m.Remove(tr)

	f := getFamily(tr.Family, true)
	for _, b := range f.Buckets {
		if b.Cond.match(tr) {
			b.Add(tr)
		}
	}
	// Add a sample of elapsed time as microseconds to the family's timeseries
	h := new(histogram)
	h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3)
	f.LatencyMu.Lock()
	f.Latency.Add(h)
	f.LatencyMu.Unlock()

	tr.unref() // matches ref in New
}

const (
	bucketsPerFamily    = 9
	tracesPerBucket     = 10
	maxActiveTraces     = 20 // Maximum number of active traces to show.
	maxEventsPerTrace   = 10
	numHistogramBuckets = 38
)

var (
	// The active traces.
	activeMu     sync.RWMutex
	activeTraces = make(map[string]*traceSet) // family -> traces

	// Families of completed traces.
	completedMu     sync.RWMutex
	completedTraces = make(map[string]*family) // family -> traces
)

type traceSet struct {
	mu sync.RWMutex
	m  map[*trace]bool

	// We could avoid the entire map scan in FirstN by having a slice of all the traces
	// ordered by start time, and an index into that from the trace struct, with a periodic
	// repack of the slice after enough traces finish; we could also use a skip list or similar.
	// However, that would shift some of the expense from /debug/requests time to RPC time,
	// which is probably the wrong trade-off.
}

func (ts *traceSet) Len() int {
	ts.mu.RLock()
	defer ts.mu.RUnlock()
	return len(ts.m)
}

func (ts *traceSet) Add(tr *trace) {
	ts.mu.Lock()
	if ts.m == nil {
		ts.m = make(map[*trace]bool)
	}
	ts.m[tr] = true
	ts.mu.Unlock()
}

func (ts *traceSet) Remove(tr *trace) {
	ts.mu.Lock()
	delete(ts.m, tr)
	ts.mu.Unlock()
}

// FirstN returns the first n traces ordered by time.
func (ts *traceSet) FirstN(n int) traceList {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	if n > len(ts.m) {
		n = len(ts.m)
	}
	trl := make(traceList, 0, n)

	// Fast path for when no selectivity is needed.
	if n == len(ts.m) {
		for tr := range ts.m {
			tr.ref()
			trl = append(trl, tr)
		}
		sort.Sort(trl)
		return trl
	}

	// Pick the oldest n traces.
	// This is inefficient. See the comment in the traceSet struct.
	for tr := range ts.m {
		// Put the first n traces into trl in the order they occur.
		// When we have n, sort trl, and thereafter maintain its order.
		if len(trl) < n {
			tr.ref()
			trl = append(trl, tr)
			if len(trl) == n {
				// This is guaranteed to happen exactly once during this loop.
				sort.Sort(trl)
			}
			continue
		}
		if tr.Start.After(trl[n-1].Start) {
			continue
		}

		// Find where to insert this one.
		tr.ref()
		i := sort.Search(n, func(i int) bool { return trl[i].Start.After(tr.Start) })
		trl[n-1].unref()
		copy(trl[i+1:], trl[i:])
		trl[i] = tr
	}

	return trl
}

func getActiveTraces(fam string) traceList {
	activeMu.RLock()
	s := activeTraces[fam]
	activeMu.RUnlock()
	if s == nil {
		return nil
	}
	return s.FirstN(maxActiveTraces)
}

func getFamily(fam string, allocNew bool) *family {
	completedMu.RLock()
	f := completedTraces[fam]
	completedMu.RUnlock()
	if f == nil && allocNew {
		f = allocFamily(fam)
	}
	return f
}

func allocFamily(fam string) *family {
	completedMu.Lock()
	defer completedMu.Unlock()
	f := completedTraces[fam]
	if f == nil {
		f = newFamily()
		completedTraces[fam] = f
	}
	return f
}

// family represents a set of trace buckets and associated latency information.
type family struct {
	// traces may occur in multiple buckets.
	Buckets [bucketsPerFamily]*traceBucket

	// latency time series
	LatencyMu sync.RWMutex
	Latency   *timeseries.MinuteHourSeries
}

func newFamily() *family {
	return &family{
		Buckets: [bucketsPerFamily]*traceBucket{
			{Cond: minCond(0)},
			{Cond: minCond(50 * time.Millisecond)},
			{Cond: minCond(100 * time.Millisecond)},
			{Cond: minCond(200 * time.Millisecond)},
			{Cond: minCond(500 * time.Millisecond)},
			{Cond: minCond(1 * time.Second)},
			{Cond: minCond(10 * time.Second)},
			{Cond: minCond(100 * time.Second)},
			{Cond: errorCond{}},
		},
		Latency: timeseries.NewMinuteHourSeries(func() timeseries.Observable { return new(histogram) }),
	}
}

// traceBucket represents a size-capped bucket of historic traces,
// along with a condition for a trace to belong to the bucket.
type traceBucket struct {
	Cond cond

	// Ring buffer implementation of a fixed-size FIFO queue.
	mu     sync.RWMutex
	buf    [tracesPerBucket]*trace
	start  int // < tracesPerBucket
	length int // <= tracesPerBucket
}

func (b *traceBucket) Add(tr *trace) {
	b.mu.Lock()
	defer b.mu.Unlock()

	i := b.start + b.length
	if i >= tracesPerBucket {
		i -= tracesPerBucket
	}
	if b.length == tracesPerBucket {
		// "Remove" an element from the bucket.
		b.buf[i].unref()
		b.start++
		if b.start == tracesPerBucket {
			b.start = 0
		}
	}
	b.buf[i] = tr
	if b.length < tracesPerBucket {
		b.length++
	}
	tr.ref()
}

// Copy returns a copy of the traces in the bucket.
// If tracedOnly is true, only the traces with trace information will be returned.
// The logs will be ref'd before returning; the caller should call
// the Free method when it is done with them.
// TODO(dsymonds): keep track of traced requests in separate buckets.
func (b *traceBucket) Copy(tracedOnly bool) traceList {
	b.mu.RLock()
	defer b.mu.RUnlock()

	trl := make(traceList, 0, b.length)
	for i, x := 0, b.start; i < b.length; i++ {
		tr := b.buf[x]
		if !tracedOnly || tr.spanID != 0 {
			tr.ref()
			trl = append(trl, tr)
		}
		x++
		if x == b.length {
			x = 0
		}
	}
	return trl
}

func (b *traceBucket) Empty() bool {
	b.mu.RLock()
	defer b.mu.RUnlock()
	return b.length == 0
}

// cond represents a condition on a trace.
type cond interface {
	match(t *trace) bool
	String() string
}

type minCond time.Duration

func (m minCond) match(t *trace) bool { return t.Elapsed >= time.Duration(m) }
func (m minCond) String() string      { return fmt.Sprintf("≥%gs", time.Duration(m).Seconds()) }

type errorCond struct{}

func (e errorCond) match(t *trace) bool { return t.IsError }
func (e errorCond) String() string      { return "errors" }

type traceList []*trace

// Free calls unref on each element of the list.
func (trl traceList) Free() {
	for _, t := range trl {
		t.unref()
	}
}

// traceList may be sorted in reverse chronological order.
func (trl traceList) Len() int           { return len(trl) }
func (trl traceList) Less(i, j int) bool { return trl[i].Start.After(trl[j].Start) }
func (trl traceList) Swap(i, j int)      { trl[i], trl[j] = trl[j], trl[i] }

// An event is a timestamped log entry in a trace.
type event struct {
	When       time.Time
	Elapsed    time.Duration // since previous event in trace
	NewDay     bool          // whether this event is on a different day to the previous event
	Recyclable bool          // whether this event was passed via LazyLog
	What       interface{}   // string or fmt.Stringer
	Sensitive  bool          // whether this event contains sensitive information
}

// WhenString returns a string representation of the elapsed time of the event.
// It will include the date if midnight was crossed.
func (e event) WhenString() string {
	if e.NewDay {
		return e.When.Format("2006/01/02 15:04:05.000000")
	}
	return e.When.Format("15:04:05.000000")
}

// discarded represents a number of discarded events.
// It is stored as *discarded to make it easier to update in-place.
type discarded int

func (d *discarded) String() string {
	return fmt.Sprintf("(%d events discarded)", int(*d))
}

// trace represents an active or complete request,
// either sent or received by this program.
type trace struct {
	// Family is the top-level grouping of traces to which this belongs.
	Family string

	// Title is the title of this trace.
	Title string

	// Timing information.
	Start   time.Time
	Elapsed time.Duration // zero while active

	// Trace information if non-zero.
	traceID uint64
	spanID  uint64

	// Whether this trace resulted in an error.
	IsError bool

	// Append-only sequence of events (modulo discards).
	mu     sync.RWMutex
	events []event

	refs     int32 // how many buckets this is in
	recycler func(interface{})
	disc     discarded // scratch space to avoid allocation

	finishStack []byte // where finish was called, if DebugUseAfterFinish is set
}

func (tr *trace) reset() {
	// Clear all but the mutex. Mutexes may not be copied, even when unlocked.
	tr.Family = ""
	tr.Title = ""
	tr.Start = time.Time{}
	tr.Elapsed = 0
	tr.traceID = 0
	tr.spanID = 0
	tr.IsError = false
	tr.events = nil
	tr.refs = 0
	tr.recycler = nil
	tr.disc = 0
	tr.finishStack = nil
}

// delta returns the elapsed time since the last event or the trace start,
// and whether it spans midnight.
// L >= tr.mu
func (tr *trace) delta(t time.Time) (time.Duration, bool) {
	if len(tr.events) == 0 {
		return t.Sub(tr.Start), false
	}
	prev := tr.events[len(tr.events)-1].When
	return t.Sub(prev), prev.Day() != t.Day()
}

func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) {
	if DebugUseAfterFinish && tr.finishStack != nil {
		buf := make([]byte, 4<<10) // 4 KB should be enough
		n := runtime.Stack(buf, false)
		log.Printf("net/trace: trace used after finish:\nFinished at:\n%s\nUsed at:\n%s", tr.finishStack, buf[:n])
	}

	/*
		NOTE TO DEBUGGERS

		If you are here because your program panicked in this code,
		it is almost definitely the fault of code using this package,
		and very unlikely to be the fault of this code.

		The most likely scenario is that some code elsewhere is using
		a requestz.Trace after its Finish method is called.
		You can temporarily set the DebugUseAfterFinish var
		to help discover where that is; do not leave that var set,
		since it makes this package much less efficient.
	*/

	e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive}
	tr.mu.Lock()
	e.Elapsed, e.NewDay = tr.delta(e.When)
	if len(tr.events) < cap(tr.events) {
		tr.events = append(tr.events, e)
	} else {
		// Discard the middle events.
		di := int((cap(tr.events) - 1) / 2)
		if d, ok := tr.events[di].What.(*discarded); ok {
			(*d)++
		} else {
			// disc starts at two to count for the event it is replacing,
			// plus the next one that we are about to drop.
			tr.disc = 2
			if tr.recycler != nil && tr.events[di].Recyclable {
				go tr.recycler(tr.events[di].What)
			}
			tr.events[di].What = &tr.disc
		}
		// The timestamp of the discarded meta-event should be
		// the time of the last event it is representing.
		tr.events[di].When = tr.events[di+1].When

		if tr.recycler != nil && tr.events[di+1].Recyclable {
			go tr.recycler(tr.events[di+1].What)
		}
		copy(tr.events[di+1:], tr.events[di+2:])
		tr.events[cap(tr.events)-1] = e
	}
	tr.mu.Unlock()
}

func (tr *trace) LazyLog(x fmt.Stringer, sensitive bool) {
	tr.addEvent(x, true, sensitive)
}

func (tr *trace) LazyPrintf(format string, a ...interface{}) {
	tr.addEvent(&lazySprintf{format, a}, false, false)
}

func (tr *trace) SetError() { tr.IsError = true }

func (tr *trace) SetRecycler(f func(interface{})) {
	tr.recycler = f
}

func (tr *trace) SetTraceInfo(traceID, spanID uint64) {
	tr.traceID, tr.spanID = traceID, spanID
}

func (tr *trace) SetMaxEvents(m int) {
	// Always keep at least three events: first, discarded count, last.
	if len(tr.events) == 0 && m > 3 {
		tr.events = make([]event, 0, m)
	}
}

func (tr *trace) ref() {
	atomic.AddInt32(&tr.refs, 1)
}

func (tr *trace) unref() {
	if atomic.AddInt32(&tr.refs, -1) == 0 {
		if tr.recycler != nil {
			// freeTrace clears tr, so we hold tr.recycler and tr.events here.
			go func(f func(interface{}), es []event) {
				for _, e := range es {
					if e.Recyclable {
						f(e.What)
					}
				}
			}(tr.recycler, tr.events)
		}

		freeTrace(tr)
	}
}

func (tr *trace) When() string {
	return tr.Start.Format("2006/01/02 15:04:05.000000")
}

func (tr *trace) ElapsedTime() string {
	t := tr.Elapsed
	if t == 0 {
		// Active trace.
		t = time.Since(tr.Start)
	}
	return fmt.Sprintf("%.6f", t.Seconds())
}

func (tr *trace) Events() []event {
	tr.mu.RLock()
	defer tr.mu.RUnlock()
	return tr.events
}

var traceFreeList = make(chan *trace, 1000) // TODO(dsymonds): Use sync.Pool?

// newTrace returns a trace ready to use.
func newTrace() *trace {
	select {
	case tr := <-traceFreeList:
		return tr
	default:
		return new(trace)
	}
}

// freeTrace adds tr to traceFreeList if there's room.
// This is non-blocking.
func freeTrace(tr *trace) {
	if DebugUseAfterFinish {
		return // never reuse
	}
	tr.reset()
	select {
	case traceFreeList <- tr:
	default:
	}
}

func elapsed(d time.Duration) string {
	b := []byte(fmt.Sprintf("%.6f", d.Seconds()))

	// For subsecond durations, blank all zeros before decimal point,
	// and all zeros between the decimal point and the first non-zero digit.
	if d < time.Second {
		dot := bytes.IndexByte(b, '.')
		for i := 0; i < dot; i++ {
			b[i] = ' '
		}
		for i := dot + 1; i < len(b); i++ {
			if b[i] == '0' {
				b[i] = ' '
			} else {
				break
			}
		}
	}

	return string(b)
}

var pageTmpl = template.Must(template.New("Page").Funcs(template.FuncMap{
	"elapsed": elapsed,
	"add":     func(a, b int) int { return a + b },
}).Parse(pageHTML))

const pageHTML = `
{{template "Prolog" .}}
{{template "StatusTable" .}}
{{template "Epilog" .}}

{{define "Prolog"}}
<html>
	<head>
	<title>/debug/requests</title>
	<style type="text/css">
		body {
			font-family: sans-serif;
		}
		table#tr-status td.family {
			padding-right: 2em;
		}
		table#tr-status td.active {
			padding-right: 1em;
		}
		table#tr-status td.latency-first {
			padding-left: 1em;
		}
		table#tr-status td.empty {
			color: #aaa;
		}
		table#reqs {
			margin-top: 1em;
		}
		table#reqs tr.first {
			{{if $.Expanded}}font-weight: bold;{{end}}
		}
		table#reqs td {
			font-family: monospace;
		}
		table#reqs td.when {
			text-align: right;
			white-space: nowrap;
		}
		table#reqs td.elapsed {
			padding: 0 0.5em;
			text-align: right;
			white-space: pre;
			width: 10em;
		}
		address {
			font-size: smaller;
			margin-top: 5em;
		}
	</style>
	</head>
	<body>

<h1>/debug/requests</h1>
{{end}} {{/* end of Prolog */}}

{{define "StatusTable"}}
<table id="tr-status">
	{{range $fam := .Families}}
	<tr>
		<td class="family">{{$fam}}</td>

		{{$n := index $.ActiveTraceCount $fam}}
		<td class="active {{if not $n}}empty{{end}}">
			{{if $n}}<a href="?fam={{$fam}}&b=-1{{if $.Expanded}}&exp=1{{end}}">{{end}}
			[{{$n}} active]
			{{if $n}}</a>{{end}}
		</td>

		{{$f := index $.CompletedTraces $fam}}
		{{range $i, $b := $f.Buckets}}
		{{$empty := $b.Empty}}
		<td {{if $empty}}class="empty"{{end}}>
		{{if not $empty}}<a href="?fam={{$fam}}&b={{$i}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
		[{{.Cond}}]
		{{if not $empty}}</a>{{end}}
		</td>
		{{end}}

		{{$nb := len $f.Buckets}}
		<td class="latency-first">
		<a href="?fam={{$fam}}&b={{$nb}}">[minute]</a>
		</td>
		<td>
		<a href="?fam={{$fam}}&b={{add $nb 1}}">[hour]</a>
		</td>
		<td>
		<a href="?fam={{$fam}}&b={{add $nb 2}}">[total]</a>
		</td>

	</tr>
	{{end}}
</table>
{{end}} {{/* end of StatusTable */}}

{{define "Epilog"}}
{{if $.Traces}}
<hr />
<h3>Family: {{$.Family}}</h3>

{{if or $.Expanded $.Traced}}
  <a href="?fam={{$.Family}}&b={{$.Bucket}}">[Normal/Summary]</a>
{{else}}
  [Normal/Summary]
{{end}}

{{if or (not $.Expanded) $.Traced}}
  <a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">[Normal/Expanded]</a>
{{else}}
  [Normal/Expanded]
{{end}}

{{if not $.Active}}
	{{if or $.Expanded (not $.Traced)}}
	<a href="?fam={{$.Family}}&b={{$.Bucket}}&rtraced=1">[Traced/Summary]</a>
	{{else}}
	[Traced/Summary]
	{{end}}
	{{if or (not $.Expanded) (not $.Traced)}}
	<a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1&rtraced=1">[Traced/Expanded]</a>
        {{else}}
	[Traced/Expanded]
	{{end}}
{{end}}

{{if $.Total}}
<p><em>Showing <b>{{len $.Traces}}</b> of <b>{{$.Total}}</b> traces.</em></p>
{{end}}

<table id="reqs">
	<caption>
		{{if $.Active}}Active{{else}}Completed{{end}} Requests
	</caption>
	<tr><th>When</th><th>Elapsed&nbsp;(s)</th></tr>
	{{range $tr := $.Traces}}
	<tr class="first">
		<td class="when">{{$tr.When}}</td>
		<td class="elapsed">{{$tr.ElapsedTime}}</td>
		<td>{{$tr.Title}}</td>
		{{/* TODO: include traceID/spanID */}}
	</tr>
	{{if $.Expanded}}
	{{range $tr.Events}}
	<tr>
		<td class="when">{{.WhenString}}</td>
		<td class="elapsed">{{elapsed .Elapsed}}</td>
		<td>{{if or $.ShowSensitive (not .Sensitive)}}... {{.What}}{{else}}<em>[redacted]</em>{{end}}</td>
	</tr>
	{{end}}
	{{end}}
	{{end}}
</table>
{{end}} {{/* if $.Traces */}}

{{if $.Histogram}}
<h4>Latency (&micro;s) of {{$.Family}} over {{$.HistogramWindow}}</h4>
{{$.Histogram}}
{{end}} {{/* if $.Histogram */}}

	</body>
</html>
{{end}} {{/* end of Epilog */}}
`
