// Copyright 2019 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 bench_test

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"

	benchpb "google.golang.org/protobuf/internal/testprotos/benchmarks"
	_ "google.golang.org/protobuf/internal/testprotos/benchmarks/datasets/google_message1/proto2"
	_ "google.golang.org/protobuf/internal/testprotos/benchmarks/datasets/google_message1/proto3"
	_ "google.golang.org/protobuf/internal/testprotos/benchmarks/datasets/google_message2"
	_ "google.golang.org/protobuf/internal/testprotos/benchmarks/datasets/google_message3"
	_ "google.golang.org/protobuf/internal/testprotos/benchmarks/datasets/google_message4"
)

func BenchmarkWire(b *testing.B) {
	bench(b, "Unmarshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, p := range ds.wire {
				m := ds.messageType.New().Interface()
				if err := proto.Unmarshal(p, m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
	bench(b, "Marshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, m := range ds.messages {
				if _, err := proto.Marshal(m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
	bench(b, "Size", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, m := range ds.messages {
				proto.Size(m)
			}
		}
	})
}

func BenchmarkText(b *testing.B) {
	bench(b, "Unmarshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, p := range ds.text {
				m := ds.messageType.New().Interface()
				if err := prototext.Unmarshal(p, m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
	bench(b, "Marshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, m := range ds.messages {
				if _, err := prototext.Marshal(m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
}

func BenchmarkJSON(b *testing.B) {
	bench(b, "Unmarshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, p := range ds.json {
				m := ds.messageType.New().Interface()
				if err := protojson.Unmarshal(p, m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
	bench(b, "Marshal", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, m := range ds.messages {
				if _, err := protojson.Marshal(m); err != nil {
					b.Fatal(err)
				}
			}
		}
	})
}

func Benchmark(b *testing.B) {
	bench(b, "Clone", func(ds dataset, pb *testing.PB) {
		for pb.Next() {
			for _, src := range ds.messages {
				proto.Clone(src)
			}
		}
	})
}

func bench(b *testing.B, name string, f func(dataset, *testing.PB)) {
	b.Helper()
	b.Run(name, func(b *testing.B) {
		for _, ds := range datasets {
			b.Run(ds.name, func(b *testing.B) {
				b.RunParallel(func(pb *testing.PB) {
					f(ds, pb)
				})
			})
		}
	})
}

type dataset struct {
	name        string
	messageType protoreflect.MessageType
	messages    []proto.Message
	wire        [][]byte
	text        [][]byte
	json        [][]byte
}

var datasets []dataset

func TestMain(m *testing.M) {
	// Load benchmark data early, to avoid including this step in -cpuprofile/-memprofile.
	//
	// For the larger benchmark datasets (not downloaded by default), preparing
	// this data is quite expensive. In addition, keeping the unmarshaled messages
	// in memory makes GC scans a substantial fraction of runtime CPU cost.
	//
	// It would be nice to avoid loading the data we aren't going to use. Unfortunately,
	// there isn't any simple way to tell what benchmarks are going to run; we can examine
	// the -test.bench flag, but parsing it is quite complicated.
	flag.Parse()
	if v := flag.Lookup("test.bench").Value.(flag.Getter).Get(); v == "" {
		// Don't bother loading data if we aren't going to run any benchmarks.
		// Avoids slowing down go test ./...
		return
	}
	if v := flag.Lookup("test.timeout").Value.(flag.Getter).Get().(time.Duration); v != 0 && v <= 10*time.Minute {
		// The default test timeout of 10m is too short if running all the benchmarks.
		// It's quite frustrating to discover this 10m through a benchmark run, so
		// catch the condition.
		//
		// The -timeout and -test.timeout flags are handled by the go command, which
		// forwards them along to the test binary, so we can't just set the default
		// to something reasonable; the go command will override it with its default.
		// We also can't ignore the timeout, because the go command kills a test which
		// runs more than a minute past its deadline.
		fmt.Fprintf(os.Stderr, "Test timeout of %v is probably too short; set -test.timeout=0.\n", v)
		os.Exit(1)
	}
	out, err := exec.Command("git", "rev-parse", "--show-toplevel").CombinedOutput()
	if err != nil {
		panic(err)
	}
	repoRoot := strings.TrimSpace(string(out))
	dataDir := filepath.Join(repoRoot, ".cache", "benchdata")
	filepath.Walk(dataDir, func(path string, _ os.FileInfo, _ error) error {
		if filepath.Ext(path) != ".pb" {
			return nil
		}
		raw, err := os.ReadFile(path)
		if err != nil {
			panic(err)
		}
		dspb := &benchpb.BenchmarkDataset{}
		if err := proto.Unmarshal(raw, dspb); err != nil {
			panic(err)
		}
		mt, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(dspb.MessageName))
		if err != nil {
			panic(err)
		}
		ds := dataset{
			name:        dspb.Name,
			messageType: mt,
			wire:        dspb.Payload,
		}
		for _, payload := range dspb.Payload {
			m := mt.New().Interface()
			if err := proto.Unmarshal(payload, m); err != nil {
				panic(err)
			}
			ds.messages = append(ds.messages, m)
			b, err := prototext.Marshal(m)
			if err != nil {
				panic(err)
			}
			ds.text = append(ds.text, b)
			b, err = protojson.Marshal(m)
			if err != nil {
				panic(err)
			}
			ds.json = append(ds.json, b)
		}
		datasets = append(datasets, ds)
		return nil
	})
	os.Exit(m.Run())
}
