// 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 parse provides support for parsing benchmark results as
// generated by 'go test -bench'.
package parse // import "golang.org/x/tools/benchmark/parse"

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"strconv"
	"strings"
)

// Flags used by Benchmark.Measured to indicate
// which measurements a Benchmark contains.
const (
	NsPerOp = 1 << iota
	MBPerS
	AllocedBytesPerOp
	AllocsPerOp
)

// Benchmark is one run of a single benchmark.
type Benchmark struct {
	Name              string  // benchmark name
	N                 int     // number of iterations
	NsPerOp           float64 // nanoseconds per iteration
	AllocedBytesPerOp uint64  // bytes allocated per iteration
	AllocsPerOp       uint64  // allocs per iteration
	MBPerS            float64 // MB processed per second
	Measured          int     // which measurements were recorded
	Ord               int     // ordinal position within a benchmark run
}

// ParseLine extracts a Benchmark from a single line of testing.B
// output.
func ParseLine(line string) (*Benchmark, error) {
	fields := strings.Fields(line)

	// Two required, positional fields: Name and iterations.
	if len(fields) < 2 {
		return nil, fmt.Errorf("two fields required, have %d", len(fields))
	}
	if !strings.HasPrefix(fields[0], "Benchmark") {
		return nil, fmt.Errorf(`first field does not start with "Benchmark"`)
	}
	n, err := strconv.Atoi(fields[1])
	if err != nil {
		return nil, err
	}
	b := &Benchmark{Name: fields[0], N: n}

	// Parse any remaining pairs of fields; we've parsed one pair already.
	for i := 1; i < len(fields)/2; i++ {
		b.parseMeasurement(fields[i*2], fields[i*2+1])
	}
	return b, nil
}

func (b *Benchmark) parseMeasurement(quant string, unit string) {
	switch unit {
	case "ns/op":
		if f, err := strconv.ParseFloat(quant, 64); err == nil {
			b.NsPerOp = f
			b.Measured |= NsPerOp
		}
	case "MB/s":
		if f, err := strconv.ParseFloat(quant, 64); err == nil {
			b.MBPerS = f
			b.Measured |= MBPerS
		}
	case "B/op":
		if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
			b.AllocedBytesPerOp = i
			b.Measured |= AllocedBytesPerOp
		}
	case "allocs/op":
		if i, err := strconv.ParseUint(quant, 10, 64); err == nil {
			b.AllocsPerOp = i
			b.Measured |= AllocsPerOp
		}
	}
}

func (b *Benchmark) String() string {
	buf := new(bytes.Buffer)
	fmt.Fprintf(buf, "%s %d", b.Name, b.N)
	if (b.Measured & NsPerOp) != 0 {
		fmt.Fprintf(buf, " %.2f ns/op", b.NsPerOp)
	}
	if (b.Measured & MBPerS) != 0 {
		fmt.Fprintf(buf, " %.2f MB/s", b.MBPerS)
	}
	if (b.Measured & AllocedBytesPerOp) != 0 {
		fmt.Fprintf(buf, " %d B/op", b.AllocedBytesPerOp)
	}
	if (b.Measured & AllocsPerOp) != 0 {
		fmt.Fprintf(buf, " %d allocs/op", b.AllocsPerOp)
	}
	return buf.String()
}

// Set is a collection of benchmarks from one
// testing.B run, keyed by name to facilitate comparison.
type Set map[string][]*Benchmark

// ParseSet extracts a Set from testing.B output.
// ParseSet preserves the order of benchmarks that have identical
// names.
func ParseSet(r io.Reader) (Set, error) {
	bb := make(Set)
	scan := bufio.NewScanner(r)
	ord := 0
	for scan.Scan() {
		if b, err := ParseLine(scan.Text()); err == nil {
			b.Ord = ord
			ord++
			bb[b.Name] = append(bb[b.Name], b)
		}
	}

	if err := scan.Err(); err != nil {
		return nil, err
	}

	return bb, nil
}
