// Copyright 2022 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 benchfmt

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
	"time"
)

func parseAll(t *testing.T, data string, setup ...func(r *Reader, sr io.Reader)) ([]Record, *Reader) {
	sr := strings.NewReader(data)
	r := NewReader(sr, "test")
	for _, f := range setup {
		f(r, sr)
	}
	var out []Record
	for r.Scan() {
		switch rec := r.Result(); rec := rec.(type) {
		case *Result:
			res := rec.Clone()
			// Wipe position information for comparisons.
			res.fileName = ""
			res.line = 0
			out = append(out, res)
		case *SyntaxError, *UnitMetadata:
			out = append(out, rec)
		default:
			t.Fatalf("unexpected result type %T", rec)
		}
	}
	if err := r.Err(); err != nil {
		t.Fatal("parsing failed: ", err)
	}
	return out, r
}

func printRecord(w io.Writer, r Record) {
	switch r := r.(type) {
	case *Result:
		for _, fc := range r.Config {
			fmt.Fprintf(w, "{%s: %s} ", fc.Key, fc.Value)
		}
		fmt.Fprintf(w, "%s %d", r.Name.Full(), r.Iters)
		for _, val := range r.Values {
			fmt.Fprintf(w, " %v %s", val.Value, val.Unit)
		}
		fmt.Fprintf(w, "\n")
	case *UnitMetadata:
		fmt.Fprintf(w, "Unit: %+v\n", r)
	case *SyntaxError:
		fmt.Fprintf(w, "SyntaxError: %s\n", r)
	default:
		panic(fmt.Sprintf("unknown record type %T", r))
	}
}

type resultBuilder struct {
	res *Result
}

func r(fullName string, iters int) *resultBuilder {
	return &resultBuilder{
		&Result{
			Config: []Config{},
			Name:   Name(fullName),
			Iters:  iters,
		},
	}
}

func (b *resultBuilder) config(keyVals ...string) *resultBuilder {
	for i := 0; i < len(keyVals); i += 2 {
		key, val := keyVals[i], keyVals[i+1]
		file := true
		if val[0] == '*' {
			file = false
			val = val[1:]
		}
		b.res.Config = append(b.res.Config, Config{key, []byte(val), file})
	}
	return b
}

func (b *resultBuilder) v(value float64, unit string) *resultBuilder {
	var v Value
	if unit == "ns/op" {
		v = Value{Value: value * 1e-9, Unit: "sec/op", OrigValue: value, OrigUnit: unit}
	} else {
		v = Value{Value: value, Unit: unit}
	}
	b.res.Values = append(b.res.Values, v)
	return b
}

func compareRecords(t *testing.T, got, want []Record) {
	t.Helper()
	var diff bytes.Buffer
	for i := 0; i < len(got) || i < len(want); i++ {
		if i >= len(got) {
			fmt.Fprintf(&diff, "[%d] got: none, want:\n", i)
			printRecord(&diff, want[i])
		} else if i >= len(want) {
			fmt.Fprintf(&diff, "[%d] want: none, got:\n", i)
			printRecord(&diff, got[i])
		} else if !reflect.DeepEqual(got[i], want[i]) {
			fmt.Fprintf(&diff, "[%d] got:\n", i)
			printRecord(&diff, got[i])
			fmt.Fprintf(&diff, "[%d] want:\n", i)
			printRecord(&diff, want[i])
		}
	}
	if diff.Len() != 0 {
		t.Error(diff.String())
	}
}

func TestReader(t *testing.T) {
	type testCase struct {
		name, input string
		want        []Record
	}
	for _, test := range []testCase{
		{
			"basic",
			`key: value
BenchmarkOne 100 1 ns/op 2 B/op
BenchmarkTwo 300 4.5 ns/op
`,
			[]Record{
				r("One", 100).
					config("key", "value").
					v(1, "ns/op").v(2, "B/op").res,
				r("Two", 300).
					config("key", "value").
					v(4.5, "ns/op").res,
			},
		},
		{
			"weird",
			`
BenchmarkSpaces    1   1   ns/op
BenchmarkHugeVal 1 9999999999999999999999999999999 ns/op
BenchmarkEmSpace  1  1  ns/op
`,
			[]Record{
				r("Spaces", 1).
					v(1, "ns/op").res,
				r("HugeVal", 1).
					v(9999999999999999999999999999999, "ns/op").res,
				r("EmSpace", 1).
					v(1, "ns/op").res,
			},
		},
		{
			"basic file keys",
			`key1:    	 value
: not a key
ab:not a key
a b: also not a key
key2: value

BenchmarkOne 100 1 ns/op
`,
			[]Record{
				r("One", 100).
					config("key1", "value", "key2", "value").
					v(1, "ns/op").res,
			},
		},
		{
			"bad lines",
			`not a benchmark
BenchmarkMissingIter
BenchmarkBadIter abc
BenchmarkHugeIter 9999999999999999999999999999999
BenchmarkMissingVal 100
BenchmarkBadVal 100 abc
BenchmarkMissingUnit 100 1
BenchmarkMissingUnit2 100 1 ns/op 2
also not a benchmark
Unit
Unit ns/op blah
Unit ns/op a=1
Unit ns/op a=2
`,
			[]Record{
				&SyntaxError{"test", 2, "missing iteration count"},
				&SyntaxError{"test", 3, "parsing iteration count: invalid syntax"},
				&SyntaxError{"test", 4, "parsing iteration count: value out of range"},
				&SyntaxError{"test", 5, "missing measurements"},
				&SyntaxError{"test", 6, "parsing measurement: invalid syntax"},
				&SyntaxError{"test", 7, "missing units"},
				&SyntaxError{"test", 8, "missing units"},
				&SyntaxError{"test", 10, "missing unit"},
				&SyntaxError{"test", 11, "expected key=value"},
				&UnitMetadata{UnitMetadataKey{"sec/op", "a"}, "ns/op", "1", "test", 12},
				&SyntaxError{"test", 13, "metadata a of unit ns/op already set to 1"},
			},
		},
		{
			"remove existing label",
			`key: value
key:
BenchmarkOne 100 1 ns/op
`,
			[]Record{
				r("One", 100).
					v(1, "ns/op").res,
			},
		},
		{
			"overwrite exiting label",
			`key1: first
key2: second
key1: third
BenchmarkOne 100 1 ns/op
`,
			[]Record{
				r("One", 100).
					config("key1", "third", "key2", "second").
					v(1, "ns/op").res,
			},
		},
		{
			"unit metadata",
			`Unit ns/op a=1 b=2
Unit ns/op c=3 error d=4
# Repeated unit should report nothing
Unit ns/op d=4
# Starts like a unit line but actually isn't
Unitx
BenchmarkOne 100 1 ns/op
`,
			[]Record{
				&UnitMetadata{UnitMetadataKey{"sec/op", "a"}, "ns/op", "1", "test", 1},
				&UnitMetadata{UnitMetadataKey{"sec/op", "b"}, "ns/op", "2", "test", 1},
				&UnitMetadata{UnitMetadataKey{"sec/op", "c"}, "ns/op", "3", "test", 2},
				&SyntaxError{"test", 2, "expected key=value"},
				&UnitMetadata{UnitMetadataKey{"sec/op", "d"}, "ns/op", "4", "test", 2},
				r("One", 100).
					v(1, "ns/op").res,
			},
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			got, _ := parseAll(t, test.input)
			compareRecords(t, got, test.want)
		})
	}
}

func TestReaderInternalConfig(t *testing.T) {
	got, _ := parseAll(t, `
# Test initial internal config
Benchmark1 100 1 ns/op
# Overwrite internal config with file config
key1: file1
key3: file3
Benchmark2 100 1 ns/op
# Delete internal config, check that file config is right
key2:
Benchmark3 100 1 ns/op
	`, func(r *Reader, sr io.Reader) {
		r.Reset(sr, "test", "key1", "internal1", "key2", "internal2")
	})
	want := []Record{
		r("1", 100).v(1, "ns/op").config("key1", "*internal1", "key2", "*internal2").res,
		r("2", 100).v(1, "ns/op").config("key1", "file1", "key2", "*internal2", "key3", "file3").res,
		r("3", 100).v(1, "ns/op").config("key1", "file1", "key3", "file3").res,
	}
	compareRecords(t, got, want)
}

func BenchmarkReader(b *testing.B) {
	path := "testdata/bent"
	fileInfos, err := os.ReadDir(path)
	if err != nil {
		b.Fatal("reading test data directory: ", err)
	}

	var files []*os.File
	for _, info := range fileInfos {
		f, err := os.Open(filepath.Join(path, info.Name()))
		if err != nil {
			b.Fatal(err)
		}
		defer f.Close()
		files = append(files, f)
	}

	b.ResetTimer()

	start := time.Now()
	var n int
	for i := 0; i < b.N; i++ {
		r := new(Reader)
		for _, f := range files {
			if _, err := f.Seek(0, 0); err != nil {
				b.Fatal("seeking to 0: ", err)
			}
			r.Reset(f, f.Name())
			for r.Scan() {
				n++
				if err, ok := r.Result().(error); ok {
					b.Fatal("malformed record: ", err)
				}
			}
			if err := r.Err(); err != nil {
				b.Fatal(err)
			}
		}
	}
	dur := time.Since(start)
	b.Logf("read %d records", n)

	b.StopTimer()
	b.ReportMetric(float64(n/b.N), "records/op")
	b.ReportMetric(float64(n)*float64(time.Second)/float64(dur), "records/sec")
}
