{{/*
// Copyright 2022 The Fuchsia 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 benchmark_suite

import (
	"context"
	"sync"
	"testing"

	"fidl/test/benchmarkfidl"

	"syscall/zx"
	"syscall/zx/fidl"

	"go.fuchsia.dev/fuchsia/src/lib/component"
)


type pools struct {
	bytes sync.Pool
	handleInfos sync.Pool
	handleDispositions sync.Pool
}

func newPools() *pools {
	return &pools{
		bytes: sync.Pool{
			New: func() interface{} {
				return make([]byte, zx.ChannelMaxMessageBytes)
			},
		},
		handleInfos: sync.Pool{
			New: func() interface{} {
				return make([]zx.HandleInfo, zx.ChannelMaxMessageHandles)
			},
		},
		handleDispositions: sync.Pool{
			New: func() interface{} {
				return make([]zx.HandleDisposition, zx.ChannelMaxMessageHandles)
			},
		},
	}
}

func (p *pools) useOnce() {
	p.bytes.Put(p.bytes.Get().([]byte))
	p.handleInfos.Put(p.handleInfos.Get().([]zx.HandleInfo))
	p.handleDispositions.Put(p.handleDispositions.Get().([]zx.HandleDisposition))
}

{{ range .Benchmarks }}
func BenchmarkEncode{{ .Name }}(b *testing.B) {
	pools := newPools()
	pools.useOnce()
	input := {{ .Value }}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// This should be kept in sync with the buffer allocation strategy used in Go bindings.
		respb := pools.bytes.Get().([]byte)
		resphd := pools.handleDispositions.Get().([]zx.HandleDisposition)
		_, _, err := fidl.Marshal(fidl.NewCtx(), &input, respb, resphd)
		if err != nil {
			b.Fatal(err)
		}
		pools.bytes.Put(respb)
		pools.handleDispositions.Put(resphd)
	}
}

func BenchmarkDecode{{ .Name }}(b *testing.B) {
	data := make([]byte, 65536)
	input := {{ .Value }}
	_, _, err := fidl.Marshal(fidl.NewCtx(), &input, data, nil)
	if err != nil {
		b.Fatal(err)
	}

	var output {{ .ValueType }}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		err := fidl.Unmarshal(fidl.NewCtx(), data, nil, &output)
		if err != nil {
			b.Fatal(err)
		}
	}
}

{{ if .EnableSendEventBenchmark }}
func BenchmarkSendEvent{{ .Name }}(b *testing.B) {
	sender_end, recipient_end, err := zx.NewChannel(0)
	if err != nil {
		b.Fatal(err)
	}
	defer sender_end.Close()
	defer recipient_end.Close()
	sender_proxy := {{ .ValueType }}EventProtocolEventProxy(fidl.ChannelProxy{Channel: sender_end})
	recipient_proxy := {{ .ValueType }}EventProtocolWithCtxInterface(fidl.ChannelProxy{Channel: recipient_end})

	input := {{ .Value }}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := sender_proxy.Send(input); err != nil {
			b.Fatal(err)
		}
		if _, err := recipient_proxy.ExpectSend(context.Background()); err != nil {
			b.Fatal(err)
		}
	}
}
{{ end }}

{{ if .EnableEchoCallBenchmark }}
type {{ .Name }}EchoCallService struct {}

func (s *{{ .Name }}EchoCallService) Echo(ctx fidl.Context, val {{ .ValueType }}) ({{ .ValueType }}, error) {
	return val, nil
}

func BenchmarkEchoCall{{ .Name }}(b *testing.B) {
	client_end, server_end, err := zx.NewChannel(0)
	if err != nil {
		b.Fatal(err)
	}
	defer client_end.Close()
	stub := &{{ .ValueType }}EchoCallWithCtxStub{
		Impl: &{{ .Name }}EchoCallService{},
	}
	go component.Serve(context.Background(), stub, server_end, component.ServeOptions{
		OnError: func (err error) {
			b.Fatal(err)
		},
	})
	proxy := {{ .ValueType }}EchoCallWithCtxInterface(fidl.ChannelProxy{Channel: client_end})

	input := {{ .Value }}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, err := proxy.Echo(context.Background(), input); err != nil {
			b.Fatal(err)
		}
	}
}
{{- end -}}
{{ end }}

type Benchmark struct {
	Label string
	BenchFunc func(*testing.B)
}

// Benchmarks is read by go_fidl_benchmarks_lib.
var Benchmarks = []Benchmark{
{{ range .Benchmarks }}
	{
		Label: "Encode/{{ .ChromeperfPath }}",
		BenchFunc: BenchmarkEncode{{ .Name }},
	},
	{
		Label: "Decode/{{ .ChromeperfPath }}",
		BenchFunc: BenchmarkDecode{{ .Name }},
	},
	{{ if .EnableSendEventBenchmark }}
	{
		Label: "SendEvent/{{ .ChromeperfPath }}",
		BenchFunc: BenchmarkSendEvent{{ .Name }},
	},
	{{- end -}}
	{{ if .EnableEchoCallBenchmark }}
	{
		Label: "EchoCall/{{ .ChromeperfPath }}",
		BenchFunc: BenchmarkEchoCall{{ .Name }},
	},
	{{- end -}}
{{ end }}
}
