// Copyright 2014 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 report summarizes a performance profile into a
// human-readable report.
package report

import (
	"fmt"
	"io"
	"math"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"cmd/pprof/internal/plugin"
	"cmd/pprof/internal/profile"
)

// Generate generates a report as directed by the Report.
func Generate(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
	o := rpt.options

	switch o.OutputFormat {
	case Dot:
		return printDOT(w, rpt)
	case Tree:
		return printTree(w, rpt)
	case Text:
		return printText(w, rpt)
	case Raw:
		fmt.Fprint(w, rpt.prof.String())
		return nil
	case Tags:
		return printTags(w, rpt)
	case Proto:
		return rpt.prof.Write(w)
	case Dis:
		return printAssembly(w, rpt, obj)
	case List:
		return printSource(w, rpt)
	case WebList:
		return printWebSource(w, rpt, obj)
	case Callgrind:
		return printCallgrind(w, rpt)
	}
	return fmt.Errorf("unexpected output format")
}

// printAssembly prints an annotated assembly listing.
func printAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
	g, err := newGraph(rpt)
	if err != nil {
		return err
	}

	o := rpt.options
	prof := rpt.prof

	// If the regexp source can be parsed as an address, also match
	// functions that land on that address.
	var address *uint64
	if hex, err := strconv.ParseUint(o.Symbol.String(), 0, 64); err == nil {
		address = &hex
	}

	fmt.Fprintln(w, "Total:", rpt.formatValue(rpt.total))
	symbols := symbolsFromBinaries(prof, g, o.Symbol, address, obj)
	symNodes := nodesPerSymbol(g.ns, symbols)
	// Sort function names for printing.
	var syms objSymbols
	for s := range symNodes {
		syms = append(syms, s)
	}
	sort.Sort(syms)

	// Correlate the symbols from the binary with the profile samples.
	for _, s := range syms {
		sns := symNodes[s]

		// Gather samples for this symbol.
		flatSum, cumSum := sumNodes(sns)

		// Get the function assembly.
		insns, err := obj.Disasm(s.sym.File, s.sym.Start, s.sym.End)
		if err != nil {
			return err
		}

		ns := annotateAssembly(insns, sns, s.base)

		fmt.Fprintf(w, "ROUTINE ======================== %s\n", s.sym.Name[0])
		for _, name := range s.sym.Name[1:] {
			fmt.Fprintf(w, "    AKA ======================== %s\n", name)
		}
		fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
			rpt.formatValue(flatSum), rpt.formatValue(cumSum),
			percentage(cumSum, rpt.total))

		for _, n := range ns {
			fmt.Fprintf(w, "%10s %10s %10x: %s\n", valueOrDot(n.flat, rpt), valueOrDot(n.cum, rpt), n.info.address, n.info.name)
		}
	}
	return nil
}

// symbolsFromBinaries examines the binaries listed on the profile
// that have associated samples, and identifies symbols matching rx.
func symbolsFromBinaries(prof *profile.Profile, g graph, rx *regexp.Regexp, address *uint64, obj plugin.ObjTool) []*objSymbol {
	hasSamples := make(map[string]bool)
	// Only examine mappings that have samples that match the
	// regexp. This is an optimization to speed up pprof.
	for _, n := range g.ns {
		if name := n.info.prettyName(); rx.MatchString(name) && n.info.objfile != "" {
			hasSamples[n.info.objfile] = true
		}
	}

	// Walk all mappings looking for matching functions with samples.
	var objSyms []*objSymbol
	for _, m := range prof.Mapping {
		if !hasSamples[filepath.Base(m.File)] {
			if address == nil || !(m.Start <= *address && *address <= m.Limit) {
				continue
			}
		}

		f, err := obj.Open(m.File, m.Start)
		if err != nil {
			fmt.Printf("%v\n", err)
			continue
		}

		// Find symbols in this binary matching the user regexp.
		var addr uint64
		if address != nil {
			addr = *address
		}
		msyms, err := f.Symbols(rx, addr)
		base := f.Base()
		f.Close()
		if err != nil {
			continue
		}
		for _, ms := range msyms {
			objSyms = append(objSyms,
				&objSymbol{
					sym:  ms,
					base: base,
				},
			)
		}
	}

	return objSyms
}

// objSym represents a symbol identified from a binary. It includes
// the SymbolInfo from the disasm package and the base that must be
// added to correspond to sample addresses
type objSymbol struct {
	sym  *plugin.Sym
	base uint64
}

// objSymbols is a wrapper type to enable sorting of []*objSymbol.
type objSymbols []*objSymbol

func (o objSymbols) Len() int {
	return len(o)
}

func (o objSymbols) Less(i, j int) bool {
	if namei, namej := o[i].sym.Name[0], o[j].sym.Name[0]; namei != namej {
		return namei < namej
	}
	return o[i].sym.Start < o[j].sym.Start
}

func (o objSymbols) Swap(i, j int) {
	o[i], o[j] = o[j], o[i]
}

// nodesPerSymbol classifies nodes into a group of symbols.
func nodesPerSymbol(ns nodes, symbols []*objSymbol) map[*objSymbol]nodes {
	symNodes := make(map[*objSymbol]nodes)
	for _, s := range symbols {
		// Gather samples for this symbol.
		for _, n := range ns {
			address := n.info.address - s.base
			if address >= s.sym.Start && address < s.sym.End {
				symNodes[s] = append(symNodes[s], n)
			}
		}
	}
	return symNodes
}

// annotateAssembly annotates a set of assembly instructions with a
// set of samples. It returns a set of nodes to display.  base is an
// offset to adjust the sample addresses.
func annotateAssembly(insns []plugin.Inst, samples nodes, base uint64) nodes {
	// Add end marker to simplify printing loop.
	insns = append(insns, plugin.Inst{^uint64(0), "", "", 0})

	// Ensure samples are sorted by address.
	samples.sort(addressOrder)

	var s int
	var asm nodes
	for ix, in := range insns[:len(insns)-1] {
		n := node{
			info: nodeInfo{
				address: in.Addr,
				name:    in.Text,
				file:    trimPath(in.File),
				lineno:  in.Line,
			},
		}

		// Sum all the samples until the next instruction (to account
		// for samples attributed to the middle of an instruction).
		for next := insns[ix+1].Addr; s < len(samples) && samples[s].info.address-base < next; s++ {
			n.flat += samples[s].flat
			n.cum += samples[s].cum
			if samples[s].info.file != "" {
				n.info.file = trimPath(samples[s].info.file)
				n.info.lineno = samples[s].info.lineno
			}
		}
		asm = append(asm, &n)
	}

	return asm
}

// valueOrDot formats a value according to a report, intercepting zero
// values.
func valueOrDot(value int64, rpt *Report) string {
	if value == 0 {
		return "."
	}
	return rpt.formatValue(value)
}

// canAccessFile determines if the filename can be opened for reading.
func canAccessFile(path string) bool {
	if fi, err := os.Stat(path); err == nil {
		return fi.Mode().Perm()&0400 != 0
	}
	return false
}

// printTags collects all tags referenced in the profile and prints
// them in a sorted table.
func printTags(w io.Writer, rpt *Report) error {
	p := rpt.prof

	// Hashtable to keep accumulate tags as key,value,count.
	tagMap := make(map[string]map[string]int64)
	for _, s := range p.Sample {
		for key, vals := range s.Label {
			for _, val := range vals {
				if valueMap, ok := tagMap[key]; ok {
					valueMap[val] = valueMap[val] + s.Value[0]
					continue
				}
				valueMap := make(map[string]int64)
				valueMap[val] = s.Value[0]
				tagMap[key] = valueMap
			}
		}
		for key, vals := range s.NumLabel {
			for _, nval := range vals {
				val := scaledValueLabel(nval, key, "auto")
				if valueMap, ok := tagMap[key]; ok {
					valueMap[val] = valueMap[val] + s.Value[0]
					continue
				}
				valueMap := make(map[string]int64)
				valueMap[val] = s.Value[0]
				tagMap[key] = valueMap
			}
		}
	}

	tagKeys := make(tags, 0, len(tagMap))
	for key := range tagMap {
		tagKeys = append(tagKeys, &tag{name: key})
	}
	sort.Sort(tagKeys)

	for _, tagKey := range tagKeys {
		var total int64
		key := tagKey.name
		tags := make(tags, 0, len(tagMap[key]))
		for t, c := range tagMap[key] {
			total += c
			tags = append(tags, &tag{name: t, weight: c})
		}

		sort.Sort(tags)
		fmt.Fprintf(w, "%s: Total %d\n", key, total)
		for _, t := range tags {
			if total > 0 {
				fmt.Fprintf(w, "  %8d (%s): %s\n", t.weight,
					percentage(t.weight, total), t.name)
			} else {
				fmt.Fprintf(w, "  %8d: %s\n", t.weight, t.name)
			}
		}
		fmt.Fprintln(w)
	}
	return nil
}

// printText prints a flat text report for a profile.
func printText(w io.Writer, rpt *Report) error {
	g, err := newGraph(rpt)
	if err != nil {
		return err
	}

	origCount, droppedNodes, _ := g.preprocess(rpt)
	fmt.Fprintln(w, strings.Join(legendDetailLabels(rpt, g, origCount, droppedNodes, 0), "\n"))

	fmt.Fprintf(w, "%10s %5s%% %5s%% %10s %5s%%\n",
		"flat", "flat", "sum", "cum", "cum")

	var flatSum int64
	for _, n := range g.ns {
		name, flat, cum := n.info.prettyName(), n.flat, n.cum

		flatSum += flat
		fmt.Fprintf(w, "%10s %s %s %10s %s  %s\n",
			rpt.formatValue(flat),
			percentage(flat, rpt.total),
			percentage(flatSum, rpt.total),
			rpt.formatValue(cum),
			percentage(cum, rpt.total),
			name)
	}
	return nil
}

// printCallgrind prints a graph for a profile on callgrind format.
func printCallgrind(w io.Writer, rpt *Report) error {
	g, err := newGraph(rpt)
	if err != nil {
		return err
	}

	o := rpt.options
	rpt.options.NodeFraction = 0
	rpt.options.EdgeFraction = 0
	rpt.options.NodeCount = 0

	g.preprocess(rpt)

	fmt.Fprintln(w, "events:", o.SampleType+"("+o.OutputUnit+")")

	files := make(map[string]int)
	names := make(map[string]int)
	for _, n := range g.ns {
		fmt.Fprintln(w, "fl="+callgrindName(files, n.info.file))
		fmt.Fprintln(w, "fn="+callgrindName(names, n.info.name))
		sv, _ := ScaleValue(n.flat, o.SampleUnit, o.OutputUnit)
		fmt.Fprintf(w, "%d %d\n", n.info.lineno, int(sv))

		// Print outgoing edges.
		for _, out := range sortedEdges(n.out) {
			c, _ := ScaleValue(out.weight, o.SampleUnit, o.OutputUnit)
			count := fmt.Sprintf("%d", int(c))
			callee := out.dest
			fmt.Fprintln(w, "cfl="+callgrindName(files, callee.info.file))
			fmt.Fprintln(w, "cfn="+callgrindName(names, callee.info.name))
			fmt.Fprintln(w, "calls="+count, callee.info.lineno)
			fmt.Fprintln(w, n.info.lineno, count)
		}
		fmt.Fprintln(w)
	}

	return nil
}

// callgrindName implements the callgrind naming compression scheme.
// For names not previously seen returns "(N) name", where N is a
// unique index.  For names previously seen returns "(N)" where N is
// the index returned the first time.
func callgrindName(names map[string]int, name string) string {
	if name == "" {
		return ""
	}
	if id, ok := names[name]; ok {
		return fmt.Sprintf("(%d)", id)
	}
	id := len(names) + 1
	names[name] = id
	return fmt.Sprintf("(%d) %s", id, name)
}

// printTree prints a tree-based report in text form.
func printTree(w io.Writer, rpt *Report) error {
	const separator = "----------------------------------------------------------+-------------"
	const legend = "      flat  flat%   sum%        cum   cum%   calls calls% + context 	 	 "

	g, err := newGraph(rpt)
	if err != nil {
		return err
	}

	origCount, droppedNodes, _ := g.preprocess(rpt)
	fmt.Fprintln(w, strings.Join(legendDetailLabels(rpt, g, origCount, droppedNodes, 0), "\n"))

	fmt.Fprintln(w, separator)
	fmt.Fprintln(w, legend)
	var flatSum int64

	rx := rpt.options.Symbol
	for _, n := range g.ns {
		name, flat, cum := n.info.prettyName(), n.flat, n.cum

		// Skip any entries that do not match the regexp (for the "peek" command).
		if rx != nil && !rx.MatchString(name) {
			continue
		}

		fmt.Fprintln(w, separator)
		// Print incoming edges.
		inEdges := sortedEdges(n.in)
		inSum := inEdges.sum()
		for _, in := range inEdges {
			fmt.Fprintf(w, "%50s %s |   %s\n", rpt.formatValue(in.weight),
				percentage(in.weight, inSum), in.src.info.prettyName())
		}

		// Print current node.
		flatSum += flat
		fmt.Fprintf(w, "%10s %s %s %10s %s                | %s\n",
			rpt.formatValue(flat),
			percentage(flat, rpt.total),
			percentage(flatSum, rpt.total),
			rpt.formatValue(cum),
			percentage(cum, rpt.total),
			name)

		// Print outgoing edges.
		outEdges := sortedEdges(n.out)
		outSum := outEdges.sum()
		for _, out := range outEdges {
			fmt.Fprintf(w, "%50s %s |   %s\n", rpt.formatValue(out.weight),
				percentage(out.weight, outSum), out.dest.info.prettyName())
		}
	}
	if len(g.ns) > 0 {
		fmt.Fprintln(w, separator)
	}
	return nil
}

// printDOT prints an annotated callgraph in DOT format.
func printDOT(w io.Writer, rpt *Report) error {
	g, err := newGraph(rpt)
	if err != nil {
		return err
	}

	origCount, droppedNodes, droppedEdges := g.preprocess(rpt)

	prof := rpt.prof
	graphname := "unnamed"
	if len(prof.Mapping) > 0 {
		graphname = filepath.Base(prof.Mapping[0].File)
	}
	fmt.Fprintln(w, `digraph "`+graphname+`" {`)
	fmt.Fprintln(w, `node [style=filled fillcolor="#f8f8f8"]`)
	fmt.Fprintln(w, dotLegend(rpt, g, origCount, droppedNodes, droppedEdges))

	if len(g.ns) == 0 {
		fmt.Fprintln(w, "}")
		return nil
	}

	// Make sure nodes have a unique consistent id.
	nodeIndex := make(map[*node]int)
	maxFlat := float64(g.ns[0].flat)
	for i, n := range g.ns {
		nodeIndex[n] = i + 1
		if float64(n.flat) > maxFlat {
			maxFlat = float64(n.flat)
		}
	}
	var edges edgeList
	for _, n := range g.ns {
		node := dotNode(rpt, maxFlat, nodeIndex[n], n)
		fmt.Fprintln(w, node)
		if nodelets := dotNodelets(rpt, nodeIndex[n], n); nodelets != "" {
			fmt.Fprint(w, nodelets)
		}

		// Collect outgoing edges.
		for _, e := range n.out {
			edges = append(edges, e)
		}
	}
	// Sort edges by frequency as a hint to the graph layout engine.
	sort.Sort(edges)
	for _, e := range edges {
		fmt.Fprintln(w, dotEdge(rpt, nodeIndex[e.src], nodeIndex[e.dest], e))
	}
	fmt.Fprintln(w, "}")
	return nil
}

// percentage computes the percentage of total of a value, and encodes
// it as a string. At least two digits of precision are printed.
func percentage(value, total int64) string {
	var ratio float64
	if total != 0 {
		ratio = float64(value) / float64(total) * 100
	}
	switch {
	case ratio >= 99.95:
		return "  100%"
	case ratio >= 1.0:
		return fmt.Sprintf("%5.2f%%", ratio)
	default:
		return fmt.Sprintf("%5.2g%%", ratio)
	}
}

// dotLegend generates the overall graph label for a report in DOT format.
func dotLegend(rpt *Report, g graph, origCount, droppedNodes, droppedEdges int) string {
	label := legendLabels(rpt)
	label = append(label, legendDetailLabels(rpt, g, origCount, droppedNodes, droppedEdges)...)
	return fmt.Sprintf(`subgraph cluster_L { L [shape=box fontsize=32 label="%s\l"] }`, strings.Join(label, `\l`))
}

// legendLabels generates labels exclusive to graph visualization.
func legendLabels(rpt *Report) []string {
	prof := rpt.prof
	o := rpt.options
	var label []string
	if len(prof.Mapping) > 0 {
		if prof.Mapping[0].File != "" {
			label = append(label, "File: "+filepath.Base(prof.Mapping[0].File))
		}
		if prof.Mapping[0].BuildID != "" {
			label = append(label, "Build ID: "+prof.Mapping[0].BuildID)
		}
	}
	if o.SampleType != "" {
		label = append(label, "Type: "+o.SampleType)
	}
	if prof.TimeNanos != 0 {
		const layout = "Jan 2, 2006 at 3:04pm (MST)"
		label = append(label, "Time: "+time.Unix(0, prof.TimeNanos).Format(layout))
	}
	if prof.DurationNanos != 0 {
		label = append(label, fmt.Sprintf("Duration: %v", time.Duration(prof.DurationNanos)))
	}
	return label
}

// legendDetailLabels generates labels common to graph and text visualization.
func legendDetailLabels(rpt *Report, g graph, origCount, droppedNodes, droppedEdges int) []string {
	nodeFraction := rpt.options.NodeFraction
	edgeFraction := rpt.options.EdgeFraction
	nodeCount := rpt.options.NodeCount

	label := []string{}

	var flatSum int64
	for _, n := range g.ns {
		flatSum = flatSum + n.flat
	}

	label = append(label, fmt.Sprintf("%s of %s total (%s)", rpt.formatValue(flatSum), rpt.formatValue(rpt.total), percentage(flatSum, rpt.total)))

	if rpt.total > 0 {
		if droppedNodes > 0 {
			label = append(label, genLabel(droppedNodes, "node", "cum",
				rpt.formatValue(int64(float64(rpt.total)*nodeFraction))))
		}
		if droppedEdges > 0 {
			label = append(label, genLabel(droppedEdges, "edge", "freq",
				rpt.formatValue(int64(float64(rpt.total)*edgeFraction))))
		}
		if nodeCount > 0 && nodeCount < origCount {
			label = append(label, fmt.Sprintf("Showing top %d nodes out of %d (cum >= %s)",
				nodeCount, origCount,
				rpt.formatValue(g.ns[len(g.ns)-1].cum)))
		}
	}
	return label
}

func genLabel(d int, n, l, f string) string {
	if d > 1 {
		n = n + "s"
	}
	return fmt.Sprintf("Dropped %d %s (%s <= %s)", d, n, l, f)
}

// dotNode generates a graph node in DOT format.
func dotNode(rpt *Report, maxFlat float64, rIndex int, n *node) string {
	flat, cum := n.flat, n.cum

	labels := strings.Split(n.info.prettyName(), "::")
	label := strings.Join(labels, `\n`) + `\n`

	flatValue := rpt.formatValue(flat)
	if flat > 0 {
		label = label + fmt.Sprintf(`%s(%s)`,
			flatValue,
			strings.TrimSpace(percentage(flat, rpt.total)))
	} else {
		label = label + "0"
	}
	cumValue := flatValue
	if cum != flat {
		if flat > 0 {
			label = label + `\n`
		} else {
			label = label + " "
		}
		cumValue = rpt.formatValue(cum)
		label = label + fmt.Sprintf(`of %s(%s)`,
			cumValue,
			strings.TrimSpace(percentage(cum, rpt.total)))
	}

	// Scale font sizes from 8 to 24 based on percentage of flat frequency.
	// Use non linear growth to emphasize the size difference.
	baseFontSize, maxFontGrowth := 8, 16.0
	fontSize := baseFontSize
	if maxFlat > 0 && flat > 0 && float64(flat) <= maxFlat {
		fontSize += int(math.Ceil(maxFontGrowth * math.Sqrt(float64(flat)/maxFlat)))
	}
	return fmt.Sprintf(`N%d [label="%s" fontsize=%d shape=box tooltip="%s (%s)"]`,
		rIndex,
		label,
		fontSize, n.info.prettyName(), cumValue)
}

// dotEdge generates a graph edge in DOT format.
func dotEdge(rpt *Report, from, to int, e *edgeInfo) string {
	w := rpt.formatValue(e.weight)
	attr := fmt.Sprintf(`label=" %s"`, w)
	if rpt.total > 0 {
		if weight := 1 + int(e.weight*100/rpt.total); weight > 1 {
			attr = fmt.Sprintf(`%s weight=%d`, attr, weight)
		}
		if width := 1 + int(e.weight*5/rpt.total); width > 1 {
			attr = fmt.Sprintf(`%s penwidth=%d`, attr, width)
		}
	}
	arrow := "->"
	if e.residual {
		arrow = "..."
	}
	tooltip := fmt.Sprintf(`"%s %s %s (%s)"`,
		e.src.info.prettyName(), arrow, e.dest.info.prettyName(), w)
	attr = fmt.Sprintf(`%s tooltip=%s labeltooltip=%s`,
		attr, tooltip, tooltip)

	if e.residual {
		attr = attr + ` style="dotted"`
	}

	if len(e.src.tags) > 0 {
		// Separate children further if source has tags.
		attr = attr + " minlen=2"
	}
	return fmt.Sprintf("N%d -> N%d [%s]", from, to, attr)
}

// dotNodelets generates the DOT boxes for the node tags.
func dotNodelets(rpt *Report, rIndex int, n *node) (dot string) {
	const maxNodelets = 4    // Number of nodelets for alphanumeric labels
	const maxNumNodelets = 4 // Number of nodelets for numeric labels

	var ts, nts tags
	for _, t := range n.tags {
		if t.unit == "" {
			ts = append(ts, t)
		} else {
			nts = append(nts, t)
		}
	}

	// Select the top maxNodelets alphanumeric labels by weight
	sort.Sort(ts)
	if len(ts) > maxNodelets {
		ts = ts[:maxNodelets]
	}
	for i, t := range ts {
		weight := rpt.formatValue(t.weight)
		dot += fmt.Sprintf(`N%d_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", rIndex, i, t.name, weight)
		dot += fmt.Sprintf(`N%d -> N%d_%d [label=" %s" weight=100 tooltip="\L" labeltooltip="\L"]`+"\n", rIndex, rIndex, i, weight)
	}

	// Collapse numeric labels into maxNumNodelets buckets, of the form:
	// 1MB..2MB, 3MB..5MB, ...
	nts = collapseTags(nts, maxNumNodelets)
	sort.Sort(nts)
	for i, t := range nts {
		weight := rpt.formatValue(t.weight)
		dot += fmt.Sprintf(`NN%d_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", rIndex, i, t.name, weight)
		dot += fmt.Sprintf(`N%d -> NN%d_%d [label=" %s" weight=100 tooltip="\L" labeltooltip="\L"]`+"\n", rIndex, rIndex, i, weight)
	}

	return dot
}

// graph summarizes a performance profile into a format that is
// suitable for visualization.
type graph struct {
	ns nodes
}

// nodes is an ordered collection of graph nodes.
type nodes []*node

// tags represent sample annotations
type tags []*tag
type tagMap map[string]*tag

type tag struct {
	name   string
	unit   string // Describe the value, "" for non-numeric tags
	value  int64
	weight int64
}

func (t tags) Len() int      { return len(t) }
func (t tags) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t tags) Less(i, j int) bool {
	if t[i].weight == t[j].weight {
		return t[i].name < t[j].name
	}
	return t[i].weight > t[j].weight
}

// node is an entry on a profiling report. It represents a unique
// program location. It can include multiple names to represent
// inlined functions.
type node struct {
	info nodeInfo // Information associated to this entry.

	// values associated to this node.
	// flat is exclusive to this node, cum includes all descendents.
	flat, cum int64

	// in and out contains the nodes immediately reaching or reached by this nodes.
	in, out edgeMap

	// tags provide additional information about subsets of a sample.
	tags tagMap
}

func (ts tags) string() string {
	var ret string
	for _, s := range ts {
		ret = ret + fmt.Sprintf("%s %s %d %d\n", s.name, s.unit, s.value, s.weight)
	}
	return ret
}

type nodeInfo struct {
	name              string
	origName          string
	address           uint64
	file              string
	startLine, lineno int
	inline            bool
	lowPriority       bool
	objfile           string
	parent            *node // Used only if creating a calltree
}

func (n *node) addTags(s *profile.Sample, weight int64) {
	// Add a tag with all string labels
	var labels []string
	for key, vals := range s.Label {
		for _, v := range vals {
			labels = append(labels, key+":"+v)
		}
	}
	if len(labels) > 0 {
		sort.Strings(labels)
		l := n.tags.findOrAddTag(strings.Join(labels, `\n`), "", 0)
		l.weight += weight
	}

	for key, nvals := range s.NumLabel {
		for _, v := range nvals {
			label := scaledValueLabel(v, key, "auto")
			l := n.tags.findOrAddTag(label, key, v)
			l.weight += weight
		}
	}
}

func (m tagMap) findOrAddTag(label, unit string, value int64) *tag {
	if l := m[label]; l != nil {
		return l
	}
	l := &tag{
		name:  label,
		unit:  unit,
		value: value,
	}
	m[label] = l
	return l
}

// collapseTags reduces the number of entries in a tagMap by merging
// adjacent nodes into ranges. It uses a greedy approach to merge
// starting with the entries with the lowest weight.
func collapseTags(ts tags, count int) tags {
	if len(ts) <= count {
		return ts
	}

	sort.Sort(ts)
	tagGroups := make([]tags, count)
	for i, t := range ts[:count] {
		tagGroups[i] = tags{t}
	}
	for _, t := range ts[count:] {
		g, d := 0, tagDistance(t, tagGroups[0][0])
		for i := 1; i < count; i++ {
			if nd := tagDistance(t, tagGroups[i][0]); nd < d {
				g, d = i, nd
			}
		}
		tagGroups[g] = append(tagGroups[g], t)
	}

	var nts tags
	for _, g := range tagGroups {
		l, w := tagGroupLabel(g)
		nts = append(nts, &tag{
			name:   l,
			weight: w,
		})
	}
	return nts
}

func tagDistance(t, u *tag) float64 {
	v, _ := ScaleValue(u.value, u.unit, t.unit)
	if v < float64(t.value) {
		return float64(t.value) - v
	}
	return v - float64(t.value)
}

func tagGroupLabel(g tags) (string, int64) {
	if len(g) == 1 {
		t := g[0]
		return scaledValueLabel(t.value, t.unit, "auto"), t.weight
	}
	min := g[0]
	max := g[0]
	w := min.weight
	for _, t := range g[1:] {
		if v, _ := ScaleValue(t.value, t.unit, min.unit); int64(v) < min.value {
			min = t
		}
		if v, _ := ScaleValue(t.value, t.unit, max.unit); int64(v) > max.value {
			max = t
		}
		w += t.weight
	}
	return scaledValueLabel(min.value, min.unit, "auto") + ".." +
		scaledValueLabel(max.value, max.unit, "auto"), w
}

// sumNodes adds the flat and sum values on a report.
func sumNodes(ns nodes) (flat int64, cum int64) {
	for _, n := range ns {
		flat += n.flat
		cum += n.cum
	}
	return
}

type edgeMap map[*node]*edgeInfo

// edgeInfo contains any attributes to be represented about edges in a graph/
type edgeInfo struct {
	src, dest *node
	// The summary weight of the edge
	weight int64
	// residual edges connect nodes that were connected through a
	// separate node, which has been removed from the report.
	residual bool
}

// bumpWeight increases the weight of an edge. If there isn't such an
// edge in the map one is created.
func bumpWeight(from, to *node, w int64, residual bool) {
	if from.out[to] != to.in[from] {
		panic(fmt.Errorf("asymmetric edges %v %v", *from, *to))
	}

	if n := from.out[to]; n != nil {
		n.weight += w
		if n.residual && !residual {
			n.residual = false
		}
		return
	}

	info := &edgeInfo{src: from, dest: to, weight: w, residual: residual}
	from.out[to] = info
	to.in[from] = info
}

// Output formats.
const (
	Proto = iota
	Dot
	Tags
	Tree
	Text
	Raw
	Dis
	List
	WebList
	Callgrind
)

// Options are the formatting and filtering options used to generate a
// profile.
type Options struct {
	OutputFormat int

	CumSort        bool
	CallTree       bool
	PrintAddresses bool
	DropNegative   bool
	Ratio          float64

	NodeCount    int
	NodeFraction float64
	EdgeFraction float64

	SampleType string
	SampleUnit string // Unit for the sample data from the profile.
	OutputUnit string // Units for data formatting in report.

	Symbol *regexp.Regexp // Symbols to include on disassembly report.
}

// newGraph summarizes performance data from a profile into a graph.
func newGraph(rpt *Report) (g graph, err error) {
	prof := rpt.prof
	o := rpt.options

	// Generate a tree for graphical output if requested.
	buildTree := o.CallTree && o.OutputFormat == Dot

	locations := make(map[uint64][]nodeInfo)
	for _, l := range prof.Location {
		locations[l.ID] = newLocInfo(l)
	}

	nm := make(nodeMap)
	for _, sample := range prof.Sample {
		if sample.Location == nil {
			continue
		}

		// Construct list of node names for sample.
		var stack []nodeInfo
		for _, loc := range sample.Location {
			id := loc.ID
			stack = append(stack, locations[id]...)
		}

		// Upfront pass to update the parent chains, to prevent the
		// merging of nodes with different parents.
		if buildTree {
			var nn *node
			for i := len(stack); i > 0; i-- {
				n := &stack[i-1]
				n.parent = nn
				nn = nm.findOrInsertNode(*n)
			}
		}

		leaf := nm.findOrInsertNode(stack[0])
		weight := rpt.sampleValue(sample)
		leaf.addTags(sample, weight)

		// Aggregate counter data.
		leaf.flat += weight
		seen := make(map[*node]bool)
		var nn *node
		for _, s := range stack {
			n := nm.findOrInsertNode(s)
			if !seen[n] {
				seen[n] = true
				n.cum += weight

				if nn != nil {
					bumpWeight(n, nn, weight, false)
				}
			}
			nn = n
		}
	}

	// Collect new nodes into a report.
	ns := make(nodes, 0, len(nm))
	for _, n := range nm {
		if rpt.options.DropNegative && n.flat < 0 {
			continue
		}
		ns = append(ns, n)
	}

	return graph{ns}, nil
}

// Create a slice of formatted names for a location.
func newLocInfo(l *profile.Location) []nodeInfo {
	var objfile string

	if m := l.Mapping; m != nil {
		objfile = filepath.Base(m.File)
	}

	if len(l.Line) == 0 {
		return []nodeInfo{
			{
				address: l.Address,
				objfile: objfile,
			},
		}
	}
	var info []nodeInfo
	numInlineFrames := len(l.Line) - 1
	for li, line := range l.Line {
		ni := nodeInfo{
			address: l.Address,
			lineno:  int(line.Line),
			inline:  li < numInlineFrames,
			objfile: objfile,
		}

		if line.Function != nil {
			ni.name = line.Function.Name
			ni.origName = line.Function.SystemName
			ni.file = line.Function.Filename
			ni.startLine = int(line.Function.StartLine)
		}

		info = append(info, ni)
	}
	return info
}

// nodeMap maps from a node info struct to a node. It is used to merge
// report entries with the same info.
type nodeMap map[nodeInfo]*node

func (m nodeMap) findOrInsertNode(info nodeInfo) *node {
	rr := m[info]
	if rr == nil {
		rr = &node{
			info: info,
			in:   make(edgeMap),
			out:  make(edgeMap),
			tags: make(map[string]*tag),
		}
		m[info] = rr
	}
	return rr
}

// preprocess does any required filtering/sorting according to the
// report options. Returns the mapping from each node to any nodes
// removed by path compression and statistics on the nodes/edges removed.
func (g *graph) preprocess(rpt *Report) (origCount, droppedNodes, droppedEdges int) {
	o := rpt.options

	// Compute total weight of current set of nodes.
	// This is <= rpt.total because of node filtering.
	var totalValue int64
	for _, n := range g.ns {
		totalValue += n.flat
	}

	// Remove nodes with value <= total*nodeFraction
	if nodeFraction := o.NodeFraction; nodeFraction > 0 {
		var removed nodes
		minValue := int64(float64(totalValue) * nodeFraction)
		kept := make(nodes, 0, len(g.ns))
		for _, n := range g.ns {
			if n.cum < minValue {
				removed = append(removed, n)
			} else {
				kept = append(kept, n)
				tagsKept := make(map[string]*tag)
				for s, t := range n.tags {
					if t.weight >= minValue {
						tagsKept[s] = t
					}
				}
				n.tags = tagsKept
			}
		}
		droppedNodes = len(removed)
		removeNodes(removed, false, false)
		g.ns = kept
	}

	// Remove edges below minimum frequency.
	if edgeFraction := o.EdgeFraction; edgeFraction > 0 {
		minEdge := int64(float64(totalValue) * edgeFraction)
		for _, n := range g.ns {
			for src, e := range n.in {
				if e.weight < minEdge {
					delete(n.in, src)
					delete(src.out, n)
					droppedEdges++
				}
			}
		}
	}

	sortOrder := flatName
	if o.CumSort {
		// Force cum sorting for graph output, to preserve connectivity.
		sortOrder = cumName
	}

	// Nodes that have flat==0 and a single in/out do not provide much
	// information. Give them first chance to be removed. Do not consider edges
	// from/to nodes that are expected to be removed.
	maxNodes := o.NodeCount
	if o.OutputFormat == Dot {
		if maxNodes > 0 && maxNodes < len(g.ns) {
			sortOrder = cumName
			g.ns.sort(cumName)
			cumCutoff := g.ns[maxNodes].cum
			for _, n := range g.ns {
				if n.flat == 0 {
					if count := countEdges(n.out, cumCutoff); count > 1 {
						continue
					}
					if count := countEdges(n.in, cumCutoff); count != 1 {
						continue
					}
					n.info.lowPriority = true
				}
			}
		}
	}

	g.ns.sort(sortOrder)
	if maxNodes > 0 {
		origCount = len(g.ns)
		for index, nodes := 0, 0; index < len(g.ns); index++ {
			nodes++
			// For DOT output, count the tags as nodes since we will draw
			// boxes for them.
			if o.OutputFormat == Dot {
				nodes += len(g.ns[index].tags)
			}
			if nodes > maxNodes {
				// Trim to the top n nodes. Create dotted edges to bridge any
				// broken connections.
				removeNodes(g.ns[index:], true, true)
				g.ns = g.ns[:index]
				break
			}
		}
	}
	removeRedundantEdges(g.ns)

	// Select best unit for profile output.
	// Find the appropriate units for the smallest non-zero sample
	if o.OutputUnit == "minimum" && len(g.ns) > 0 {
		var maxValue, minValue int64

		for _, n := range g.ns {
			if n.flat > 0 && (minValue == 0 || n.flat < minValue) {
				minValue = n.flat
			}
			if n.cum > maxValue {
				maxValue = n.cum
			}
		}
		if r := o.Ratio; r > 0 && r != 1 {
			minValue = int64(float64(minValue) * r)
			maxValue = int64(float64(maxValue) * r)
		}

		_, minUnit := ScaleValue(minValue, o.SampleUnit, "minimum")
		_, maxUnit := ScaleValue(maxValue, o.SampleUnit, "minimum")

		unit := minUnit
		if minUnit != maxUnit && minValue*100 < maxValue && o.OutputFormat != Callgrind {
			// Minimum and maximum values have different units. Scale
			// minimum by 100 to use larger units, allowing minimum value to
			// be scaled down to 0.01, except for callgrind reports since
			// they can only represent integer values.
			_, unit = ScaleValue(100*minValue, o.SampleUnit, "minimum")
		}

		if unit != "" {
			o.OutputUnit = unit
		} else {
			o.OutputUnit = o.SampleUnit
		}
	}
	return
}

// countEdges counts the number of edges below the specified cutoff.
func countEdges(el edgeMap, cutoff int64) int {
	count := 0
	for _, e := range el {
		if e.weight > cutoff {
			count++
		}
	}
	return count
}

// removeNodes removes nodes from a report, optionally bridging
// connections between in/out edges and spreading out their weights
// proportionally. residual marks new bridge edges as residual
// (dotted).
func removeNodes(toRemove nodes, bridge, residual bool) {
	for _, n := range toRemove {
		for ei := range n.in {
			delete(ei.out, n)
		}
		if bridge {
			for ei, wi := range n.in {
				for eo, wo := range n.out {
					var weight int64
					if n.cum != 0 {
						weight = int64(float64(wo.weight) * (float64(wi.weight) / float64(n.cum)))
					}
					bumpWeight(ei, eo, weight, residual)
				}
			}
		}
		for eo := range n.out {
			delete(eo.in, n)
		}
	}
}

// removeRedundantEdges removes residual edges if the destination can
// be reached through another path. This is done to simplify the graph
// while preserving connectivity.
func removeRedundantEdges(ns nodes) {
	// Walk the nodes and outgoing edges in reverse order to prefer
	// removing edges with the lowest weight.
	for i := len(ns); i > 0; i-- {
		n := ns[i-1]
		in := sortedEdges(n.in)
		for j := len(in); j > 0; j-- {
			if e := in[j-1]; e.residual && isRedundant(e) {
				delete(e.src.out, e.dest)
				delete(e.dest.in, e.src)
			}
		}
	}
}

// isRedundant determines if an edge can be removed without impacting
// connectivity of the whole graph. This is implemented by checking if the
// nodes have a common ancestor after removing the edge.
func isRedundant(e *edgeInfo) bool {
	destPred := predecessors(e, e.dest)
	if len(destPred) == 1 {
		return false
	}
	srcPred := predecessors(e, e.src)

	for n := range srcPred {
		if destPred[n] && n != e.dest {
			return true
		}
	}
	return false
}

// predecessors collects all the predecessors to node n, excluding edge e.
func predecessors(e *edgeInfo, n *node) map[*node]bool {
	seen := map[*node]bool{n: true}
	queue := []*node{n}
	for len(queue) > 0 {
		n := queue[0]
		queue = queue[1:]
		for _, ie := range n.in {
			if e == ie || seen[ie.src] {
				continue
			}
			seen[ie.src] = true
			queue = append(queue, ie.src)
		}
	}
	return seen
}

// nodeSorter is a mechanism used to allow a report to be sorted
// in different ways.
type nodeSorter struct {
	rs   nodes
	less func(i, j int) bool
}

func (s nodeSorter) Len() int           { return len(s.rs) }
func (s nodeSorter) Swap(i, j int)      { s.rs[i], s.rs[j] = s.rs[j], s.rs[i] }
func (s nodeSorter) Less(i, j int) bool { return s.less(i, j) }

type nodeOrder int

const (
	flatName nodeOrder = iota
	flatCumName
	cumName
	nameOrder
	fileOrder
	addressOrder
)

// sort reoders the entries in a report based on the specified
// ordering criteria. The result is sorted in decreasing order for
// numeric quantities, alphabetically for text, and increasing for
// addresses.
func (ns nodes) sort(o nodeOrder) error {
	var s nodeSorter

	switch o {
	case flatName:
		s = nodeSorter{ns,
			func(i, j int) bool {
				if iv, jv := ns[i].flat, ns[j].flat; iv != jv {
					return iv > jv
				}
				if ns[i].info.prettyName() != ns[j].info.prettyName() {
					return ns[i].info.prettyName() < ns[j].info.prettyName()
				}
				iv, jv := ns[i].cum, ns[j].cum
				return iv > jv
			},
		}
	case flatCumName:
		s = nodeSorter{ns,
			func(i, j int) bool {
				if iv, jv := ns[i].flat, ns[j].flat; iv != jv {
					return iv > jv
				}
				if iv, jv := ns[i].cum, ns[j].cum; iv != jv {
					return iv > jv
				}
				return ns[i].info.prettyName() < ns[j].info.prettyName()
			},
		}
	case cumName:
		s = nodeSorter{ns,
			func(i, j int) bool {
				if ns[i].info.lowPriority != ns[j].info.lowPriority {
					return ns[j].info.lowPriority
				}
				if iv, jv := ns[i].cum, ns[j].cum; iv != jv {
					return iv > jv
				}
				if ns[i].info.prettyName() != ns[j].info.prettyName() {
					return ns[i].info.prettyName() < ns[j].info.prettyName()
				}
				iv, jv := ns[i].flat, ns[j].flat
				return iv > jv
			},
		}
	case nameOrder:
		s = nodeSorter{ns,
			func(i, j int) bool {
				return ns[i].info.name < ns[j].info.name
			},
		}
	case fileOrder:
		s = nodeSorter{ns,
			func(i, j int) bool {
				return ns[i].info.file < ns[j].info.file
			},
		}
	case addressOrder:
		s = nodeSorter{ns,
			func(i, j int) bool {
				return ns[i].info.address < ns[j].info.address
			},
		}
	default:
		return fmt.Errorf("report: unrecognized sort ordering: %d", o)
	}
	sort.Sort(s)
	return nil
}

type edgeList []*edgeInfo

// sortedEdges return a slice of the edges in the map, sorted for
// visualization. The sort order is first based on the edge weight
// (higher-to-lower) and then by the node names to avoid flakiness.
func sortedEdges(edges map[*node]*edgeInfo) edgeList {
	el := make(edgeList, 0, len(edges))
	for _, w := range edges {
		el = append(el, w)
	}

	sort.Sort(el)
	return el
}

func (el edgeList) Len() int {
	return len(el)
}

func (el edgeList) Less(i, j int) bool {
	if el[i].weight != el[j].weight {
		return el[i].weight > el[j].weight
	}

	from1 := el[i].src.info.prettyName()
	from2 := el[j].src.info.prettyName()
	if from1 != from2 {
		return from1 < from2
	}

	to1 := el[i].dest.info.prettyName()
	to2 := el[j].dest.info.prettyName()

	return to1 < to2
}

func (el edgeList) Swap(i, j int) {
	el[i], el[j] = el[j], el[i]
}

func (el edgeList) sum() int64 {
	var ret int64
	for _, e := range el {
		ret += e.weight
	}
	return ret
}

// ScaleValue reformats a value from a unit to a different unit.
func ScaleValue(value int64, fromUnit, toUnit string) (sv float64, su string) {
	// Avoid infinite recursion on overflow.
	if value < 0 && -value > 0 {
		v, u := ScaleValue(-value, fromUnit, toUnit)
		return -v, u
	}
	if m, u, ok := memoryLabel(value, fromUnit, toUnit); ok {
		return m, u
	}
	if t, u, ok := timeLabel(value, fromUnit, toUnit); ok {
		return t, u
	}
	// Skip non-interesting units.
	switch toUnit {
	case "count", "sample", "unit", "minimum":
		return float64(value), ""
	default:
		return float64(value), toUnit
	}
}

func scaledValueLabel(value int64, fromUnit, toUnit string) string {
	v, u := ScaleValue(value, fromUnit, toUnit)

	sv := strings.TrimSuffix(fmt.Sprintf("%.2f", v), ".00")
	if sv == "0" || sv == "-0" {
		return "0"
	}
	return sv + u
}

func memoryLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
	fromUnit = strings.TrimSuffix(strings.ToLower(fromUnit), "s")
	toUnit = strings.TrimSuffix(strings.ToLower(toUnit), "s")

	switch fromUnit {
	case "byte", "b":
	case "kilobyte", "kb":
		value *= 1024
	case "megabyte", "mb":
		value *= 1024 * 1024
	case "gigabyte", "gb":
		value *= 1024 * 1024
	default:
		return 0, "", false
	}

	if toUnit == "minimum" || toUnit == "auto" {
		switch {
		case value < 1024:
			toUnit = "b"
		case value < 1024*1024:
			toUnit = "kb"
		case value < 1024*1024*1024:
			toUnit = "mb"
		default:
			toUnit = "gb"
		}
	}

	var output float64
	switch toUnit {
	default:
		output, toUnit = float64(value), "B"
	case "kb", "kbyte", "kilobyte":
		output, toUnit = float64(value)/1024, "kB"
	case "mb", "mbyte", "megabyte":
		output, toUnit = float64(value)/(1024*1024), "MB"
	case "gb", "gbyte", "gigabyte":
		output, toUnit = float64(value)/(1024*1024*1024), "GB"
	}
	return output, toUnit, true
}

func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
	fromUnit = strings.ToLower(fromUnit)
	if len(fromUnit) > 2 {
		fromUnit = strings.TrimSuffix(fromUnit, "s")
	}

	toUnit = strings.ToLower(toUnit)
	if len(toUnit) > 2 {
		toUnit = strings.TrimSuffix(toUnit, "s")
	}

	var d time.Duration
	switch fromUnit {
	case "nanosecond", "ns":
		d = time.Duration(value) * time.Nanosecond
	case "microsecond":
		d = time.Duration(value) * time.Microsecond
	case "millisecond", "ms":
		d = time.Duration(value) * time.Millisecond
	case "second", "sec":
		d = time.Duration(value) * time.Second
	case "cycle":
		return float64(value), "", true
	default:
		return 0, "", false
	}

	if toUnit == "minimum" || toUnit == "auto" {
		switch {
		case d < 1*time.Microsecond:
			toUnit = "ns"
		case d < 1*time.Millisecond:
			toUnit = "us"
		case d < 1*time.Second:
			toUnit = "ms"
		case d < 1*time.Minute:
			toUnit = "sec"
		case d < 1*time.Hour:
			toUnit = "min"
		case d < 24*time.Hour:
			toUnit = "hour"
		case d < 15*24*time.Hour:
			toUnit = "day"
		case d < 120*24*time.Hour:
			toUnit = "week"
		default:
			toUnit = "year"
		}
	}

	var output float64
	dd := float64(d)
	switch toUnit {
	case "ns", "nanosecond":
		output, toUnit = dd/float64(time.Nanosecond), "ns"
	case "us", "microsecond":
		output, toUnit = dd/float64(time.Microsecond), "us"
	case "ms", "millisecond":
		output, toUnit = dd/float64(time.Millisecond), "ms"
	case "min", "minute":
		output, toUnit = dd/float64(time.Minute), "mins"
	case "hour", "hr":
		output, toUnit = dd/float64(time.Hour), "hrs"
	case "day":
		output, toUnit = dd/float64(24*time.Hour), "days"
	case "week", "wk":
		output, toUnit = dd/float64(7*24*time.Hour), "wks"
	case "year", "yr":
		output, toUnit = dd/float64(365*7*24*time.Hour), "yrs"
	default:
		fallthrough
	case "sec", "second", "s":
		output, toUnit = dd/float64(time.Second), "s"
	}
	return output, toUnit, true
}

// prettyName determines the printable name to be used for a node.
func (info *nodeInfo) prettyName() string {
	var name string
	if info.address != 0 {
		name = fmt.Sprintf("%016x", info.address)
	}

	if info.name != "" {
		name = name + " " + info.name
	}

	if info.file != "" {
		name += " " + trimPath(info.file)
		if info.lineno != 0 {
			name += fmt.Sprintf(":%d", info.lineno)
		}
	}

	if info.inline {
		name = name + " (inline)"
	}

	if name = strings.TrimSpace(name); name == "" && info.objfile != "" {
		name = "[" + info.objfile + "]"
	}
	return name
}

// New builds a new report indexing the sample values interpreting the
// samples with the provided function.
func New(prof *profile.Profile, options Options, value func(s *profile.Sample) int64, unit string) *Report {
	o := &options
	if o.SampleUnit == "" {
		o.SampleUnit = unit
	}
	format := func(v int64) string {
		if r := o.Ratio; r > 0 && r != 1 {
			fv := float64(v) * r
			v = int64(fv)
		}
		return scaledValueLabel(v, o.SampleUnit, o.OutputUnit)
	}
	return &Report{prof, computeTotal(prof, value), o, value, format}
}

// NewDefault builds a new report indexing the sample values with the
// last value available.
func NewDefault(prof *profile.Profile, options Options) *Report {
	index := len(prof.SampleType) - 1
	o := &options
	if o.SampleUnit == "" {
		o.SampleUnit = strings.ToLower(prof.SampleType[index].Unit)
	}
	value := func(s *profile.Sample) int64 {
		return s.Value[index]
	}
	format := func(v int64) string {
		if r := o.Ratio; r > 0 && r != 1 {
			fv := float64(v) * r
			v = int64(fv)
		}
		return scaledValueLabel(v, o.SampleUnit, o.OutputUnit)
	}
	return &Report{prof, computeTotal(prof, value), o, value, format}
}

func computeTotal(prof *profile.Profile, value func(s *profile.Sample) int64) int64 {
	var ret int64
	for _, sample := range prof.Sample {
		ret += value(sample)
	}
	return ret
}

// Report contains the data and associated routines to extract a
// report from a profile.
type Report struct {
	prof        *profile.Profile
	total       int64
	options     *Options
	sampleValue func(*profile.Sample) int64
	formatValue func(int64) string
}

func (rpt *Report) formatTags(s *profile.Sample) (string, bool) {
	var labels []string
	for key, vals := range s.Label {
		for _, v := range vals {
			labels = append(labels, key+":"+v)
		}
	}
	for key, nvals := range s.NumLabel {
		for _, v := range nvals {
			labels = append(labels, scaledValueLabel(v, key, "auto"))
		}
	}
	if len(labels) == 0 {
		return "", false
	}
	sort.Strings(labels)
	return strings.Join(labels, `\n`), true
}
