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

import (
	"bytes"
	"fmt"
	"strings"
	"text/template"

	gidlconfig "go.fuchsia.dev/fuchsia/tools/fidl/gidl/config"
	gidlir "go.fuchsia.dev/fuchsia/tools/fidl/gidl/ir"
	gidlmixer "go.fuchsia.dev/fuchsia/tools/fidl/gidl/mixer"
	fidl "go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

var benchmarkTmpl = template.Must(template.New("benchmarkTmpls").Parse(`
#![allow(unused_imports)]
use {
	fidl::{
		encoding::{Context, Decodable, Decoder, Encoder, with_tls_encode_buf},
		handle::Handle, handle::HandleDisposition, handle::HandleInfo, handle::HandleOp,
		ObjectType, Rights, UnknownData,
	},
	fidl_benchmarkfidl{{ .CrateSuffix }} as benchmarkfidl{{ .CrateSuffix }},
	fuchsia_criterion::criterion::{BatchSize, Bencher, black_box},
	fuchsia_async::futures::{future, stream::StreamExt},
	fuchsia_zircon as zx,
	gidl_util::{HandleSubtype, create_handles, copy_handle, copy_handles_at, disown_vec},
	std::mem::ManuallyDrop
};

// BENCHMARKS is aggregated by a generated benchmark_suite.rs file, which is ultimately
// used in benchmarks in src/tests/benchmarks/fidl/rust/src/main.rs.
pub const BENCHMARKS: [(&'static str, fn(&mut Bencher)); {{ .NumBenchmarks }}] = [
{{- range .Benchmarks }}
	("Builder/{{ .ChromeperfPath }}", benchmark_{{ .Name }}_builder),
	("Encode/{{ .ChromeperfPath }}", benchmark_{{ .Name }}_encode),
	("Decode/{{ .ChromeperfPath }}", benchmark_{{ .Name }}_decode),
	{{ if .EnableSendEventBenchmark }}
	("SendEvent/{{ .ChromeperfPath }}", benchmark_{{ .Name }}_send_event),
	{{- end -}}
	{{ if .EnableEchoCallBenchmark }}
	("EchoCall/{{ .ChromeperfPath }}", benchmark_{{ .Name }}_echo_call),
	{{- end -}}
{{- end }}
];

const _V1_CONTEXT: &Context = &Context {};

{{ range .Benchmarks }}
fn benchmark_{{ .Name }}_builder(b: &mut Bencher) {
	b.iter_batched_ref(
		|| {
			{{- if .HandleDefs }}
			let handle_defs = create_handles(&{{ .HandleDefs }}).unwrap();
			unsafe { disown_vec(handle_defs) }
			{{- else }}
			{{- /* Use empty vector with b.iter_batched_ref, rather than b.iter,
				for consistency between handle and non-handle benchmarks. */}}
			Vec::<Handle>::new()
			{{- end }}
		},
		|_handle_defs| {
			{{- if .HandleDefs }}
			let handle_defs = _handle_defs.as_ref();
			{{- end }}
			black_box({{ .Value }}); {{- /* semicolon: include drop time. */}}
		},
		{{- /* Consider using LargeInput or NumIterations if this causes memory issues. */}}
		BatchSize::SmallInput,
	);
}

fn benchmark_{{ .Name }}_encode(b: &mut Bencher) {
	b.iter_batched_ref(
		|| {
			{{- if .HandleDefs }}
			let handle_defs = create_handles(&{{ .HandleDefs }}).unwrap();
			let handle_defs = unsafe { disown_vec(handle_defs) };
			let handle_defs = handle_defs.as_ref();
			{{- end }}
			{{ .Value }}
		},
		|value| {
			{{- /* Encode to TLS buffers since that's what the bindings do in practice. */}}
			with_tls_encode_buf(|bytes, handles| {
				Encoder::encode_with_context(_V1_CONTEXT, bytes, handles, value).unwrap();
				{{- /* Return the underlying heap storage of handles, since with_tls_encode_buf
					clears it after calling this closure, which otherwise would close all the
					handles. By returning the actual handles, we avoid including handle close
					time in the benchmark. Note that this means the handle vector must reallocate
					on every iteration if handles are used. */}}
				{{- if .HandleDefs }}
				std::mem::take(handles)
				{{- end }}
			}) {{- /* no semicolon: exclude drop time. */}}
		},
		{{- /* Consider using LargeInput or NumIterations if this causes memory issues. */}}
		BatchSize::SmallInput,
	);
}

fn benchmark_{{ .Name }}_decode(b: &mut Bencher) {
	b.iter_batched_ref(
		|| {
			{{- if .HandleDefs }}
			let handle_defs = create_handles(&{{ .HandleDefs }}).unwrap();
			let handle_defs = unsafe { disown_vec(handle_defs) };
			let handle_defs = handle_defs.as_ref();
			{{- end }}
			let mut bytes = Vec::<u8>::new();
			let mut handles = Vec::<HandleDisposition<'static>>::new();
			let original_value = &mut {{ .Value }};
			Encoder::encode_with_context(_V1_CONTEXT, &mut bytes, &mut handles, original_value).unwrap();
			let handle_infos : Vec::<HandleInfo> = handles.into_iter().map(|h| {
				HandleInfo {
					handle: match h.handle_op {
						HandleOp::Move(hdl) => hdl,
						_ => panic!("unexpected handle op"),
					},
					object_type: h.object_type,
					rights: h.rights,
				}
			}).collect();
			{{- /* Wrap handle in an Option to allow low-overhead measurement of drop time */}}
			(bytes, handle_infos, ManuallyDrop::new({{ .ValueType }}::new_empty()))
		},
		|(bytes, handle_infos, manually_drop_value)| {
			// Cast &mut ManuallyDrop<T> to &mut T.
			let value : &mut {{ .ValueType }} = unsafe { std::mem::transmute(manually_drop_value as *mut _) };
			Decoder::decode_with_context(_V1_CONTEXT, bytes, handle_infos, value).unwrap();
			// Count the drop time in the benchmark.
			unsafe { ManuallyDrop::drop(manually_drop_value) };
		},
		{{- /* Consider using LargeInput or NumIterations if this causes memory issues. */}}
		BatchSize::SmallInput,
	);
}

{{ if .EnableSendEventBenchmark }}
async fn {{ .Name }}_send_event_receiver_thread(receiver_fidl_chan_end: zx::Channel, sender_fifo: std::sync::mpsc::SyncSender<()>) {
	let async_receiver_fidl_chan_end = fuchsia_async::Channel::from_channel(receiver_fidl_chan_end).unwrap();
	let proxy = {{ .ValueType }}EventProtocolProxy::new(async_receiver_fidl_chan_end);
	let mut event_stream = proxy.take_event_stream();
	while let Some(_event) = event_stream.next().await {
		sender_fifo.send(()).unwrap();
	};
}

fn benchmark_{{ .Name }}_send_event(b: &mut Bencher) {
	let (sender_fifo, receiver_fifo) = std::sync::mpsc::sync_channel(1);
	let (sender_fidl_chan_end, receiver_fidl_chan_end) = zx::Channel::create().unwrap();
	std::thread::spawn(|| {
		fuchsia_async::Executor::new()
			.unwrap()
			.run_singlethreaded(async move {
			{{ .Name }}_send_event_receiver_thread(receiver_fidl_chan_end, sender_fifo).await;
		});
	});
	fuchsia_async::Executor::new()
		.unwrap()
		.run_singlethreaded(async move {
			let async_sender_fidl_chan_end = fuchsia_async::Channel::from_channel(sender_fidl_chan_end).unwrap();
			let sender = <{{ .ValueType }}EventProtocolRequestStream as fidl::endpoints::RequestStream>::from_channel(async_sender_fidl_chan_end);
			b.iter_batched_ref(|| {
				{{- if .HandleDefs }}
				let handle_defs = create_handles(&{{ .HandleDefs }}).unwrap();
				let handle_defs = unsafe { disown_vec(handle_defs) };
				let handle_defs = handle_defs.as_ref();
				{{- end }}
				{{ .Value }}
			},
			|value| {
				fidl::endpoints::RequestStream::control_handle(&sender).send_send_(value).unwrap();
				receiver_fifo.recv().unwrap();
			},
			BatchSize::SmallInput);
		});
}
{{- end -}}

{{ if .EnableEchoCallBenchmark }}
async fn {{ .Name }}_echo_call_server_thread(server_end: zx::Channel) {
	let async_server_end = fuchsia_async::Channel::from_channel(server_end).unwrap();
	let stream = <{{ .ValueType }}EchoCallRequestStream as fidl::endpoints::RequestStream>::from_channel(async_server_end);
    const MAX_CONCURRENT: usize = 10;
    stream.for_each_concurrent(MAX_CONCURRENT, |request| {
		match request {
			Ok({{ .ValueType }}EchoCallRequest::Echo { mut val, responder }) => {
				responder.send(&mut val).unwrap();
			},
			Err(_) => {
				panic!("unexpected err request")
			},
		}
		future::ready(())
	}).await;
}

fn benchmark_{{ .Name }}_echo_call(b: &mut Bencher) {
	let (client_end, server_end) = zx::Channel::create().unwrap();
	std::thread::spawn(|| {
		fuchsia_async::Executor::new()
			.unwrap()
			.run_singlethreaded(async move {
			{{ .Name }}_echo_call_server_thread(server_end).await;
		});
	});
	let mut proxy = {{ .ValueType }}EchoCallSynchronousProxy::new(client_end);
	b.iter_batched_ref(|| {
		{{- if .HandleDefs }}
		let handle_defs = create_handles(&{{ .HandleDefs }}).unwrap();
		let handle_defs = unsafe { disown_vec(handle_defs) };
		let handle_defs = handle_defs.as_ref();
		{{- end }}
		{{ .Value }}
	},
	|value| {
		proxy.echo(value, zx::Time::after(zx::Duration::from_seconds(1))).unwrap();
	},
	BatchSize::SmallInput);
}
{{- end -}}
{{ end }}
`))

type benchmarkTmplInput struct {
	NumBenchmarks int
	CrateSuffix   string
	Benchmarks    []benchmark
}
type benchmark struct {
	Name, ChromeperfPath, HandleDefs, Value, ValueType string
	EnableSendEventBenchmark, EnableEchoCallBenchmark  bool
}

// GenerateBenchmarks generates Rust benchmarks.
func GenerateBenchmarks(gidl gidlir.All, fidl fidl.Root, config gidlconfig.GeneratorConfig) ([]byte, error) {
	schema := gidlmixer.BuildSchema(fidl)
	var benchmarks []benchmark
	nBenchmarks := 0
	for _, gidlBenchmark := range gidl.Benchmark {
		decl, err := schema.ExtractDeclaration(gidlBenchmark.Value, gidlBenchmark.HandleDefs)
		if err != nil {
			return nil, fmt.Errorf("benchmark %s: %s", gidlBenchmark.Name, err)
		}
		value := visit(gidlBenchmark.Value, decl)
		benchmarks = append(benchmarks, benchmark{
			Name:                     benchmarkName(gidlBenchmark.Name),
			ChromeperfPath:           gidlBenchmark.Name,
			HandleDefs:               buildHandleDefs(gidlBenchmark.HandleDefs),
			Value:                    value,
			ValueType:                declName(decl),
			EnableSendEventBenchmark: gidlBenchmark.EnableSendEventBenchmark,
			EnableEchoCallBenchmark:  gidlBenchmark.EnableEchoCallBenchmark,
		})
		nBenchmarks += 3
		if gidlBenchmark.EnableSendEventBenchmark {
			nBenchmarks++
		}
		if gidlBenchmark.EnableEchoCallBenchmark {
			nBenchmarks++
		}
	}
	input := benchmarkTmplInput{
		NumBenchmarks: nBenchmarks,
		CrateSuffix:   config.RustBenchmarksFidlLibrary,
		Benchmarks:    benchmarks,
	}
	var buf bytes.Buffer
	err := benchmarkTmpl.Execute(&buf, input)
	return buf.Bytes(), err
}

func benchmarkName(gidlName string) string {
	return fidl.ToSnakeCase(strings.ReplaceAll(gidlName, "/", "_"))
}
