/*
 * Copyright 2018 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#[macro_use]
extern crate bencher;
use bencher::Bencher;

extern crate flatbuffers;

#[path = "../../monster_test_generated.rs"]
mod monster_test_generated;
pub use monster_test_generated::my_game;

fn traverse_canonical_buffer(bench: &mut Bencher) {
    let owned_data = {
        let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
        create_serialized_example_with_generated_code(&mut builder, true);
        builder.finished_data().to_vec()
    };
    let data = &owned_data[..];
    let n = data.len() as u64;
    bench.iter(|| {
        traverse_serialized_example_with_generated_code(data);
    });
    bench.bytes = n;
}

fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
    let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
    // warmup
    create_serialized_example_with_generated_code(&mut builder, true);
    let n = builder.finished_data().len() as u64;
    builder.reset();

    bench.iter(|| {
        let _ = create_serialized_example_with_generated_code(&mut builder, true);
        builder.reset();
    });

    bench.bytes = n;
}

#[inline(always)]
fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize{
    let s0 = builder.create_string("test1");
    let s1 = builder.create_string("test2");
    let t0_name = builder.create_string("Barney");
    let t1_name = builder.create_string("Fred");
    let t2_name = builder.create_string("Wilma");
    let t0 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
        hp: 1000,
        name: Some(t0_name),
        ..Default::default()
    });
    let t1 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
        name: Some(t1_name),
        ..Default::default()
    });
    let t2 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
        name: Some(t2_name),
        ..Default::default()
    });
    let mon = {
        let name = builder.create_string("MyMonster");
        let fred_name = builder.create_string("Fred");
        let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
        let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
                                                   my_game::example::Test::new(30, 40)]);
        let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
        let args = my_game::example::MonsterArgs{
            hp: 80,
            mana: 150,
            name: Some(name),
            pos: Some(&pos),
            test_type: my_game::example::Any::Monster,
            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
                name: Some(fred_name),
                ..Default::default()
            }).as_union_value()),
            inventory: Some(inventory),
            test4: Some(test4),
            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
            testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
            ..Default::default()
        };
        my_game::example::Monster::create(builder, &args)
    };
    if finish {
        my_game::example::finish_monster_buffer(builder, mon);
    }

    builder.finished_data().len()

    // make it do some work
    // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
}

#[inline(always)]
fn blackbox<T>(t: T) -> T {
    // encapsulate this in case we need to turn it into a noop
    bencher::black_box(t)
}

#[inline(always)]
fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
    let m = my_game::example::get_root_as_monster(bytes);
    blackbox(m.hp());
    blackbox(m.mana());
    blackbox(m.name());
    let pos = m.pos().unwrap();
    blackbox(pos.x());
    blackbox(pos.y());
    blackbox(pos.z());
    blackbox(pos.test1());
    blackbox(pos.test2());
    let pos_test3 = pos.test3();
    blackbox(pos_test3.a());
    blackbox(pos_test3.b());
    blackbox(m.test_type());
    let table2 = m.test().unwrap();
    let monster2 = my_game::example::Monster::init_from_table(table2);
    blackbox(monster2.name());
    blackbox(m.inventory());
    blackbox(m.test4());
    let testarrayoftables = m.testarrayoftables().unwrap();
    blackbox(testarrayoftables.get(0).hp());
    blackbox(testarrayoftables.get(0).name());
    blackbox(testarrayoftables.get(1).name());
    blackbox(testarrayoftables.get(2).name());
    let testarrayofstring = m.testarrayofstring().unwrap();
    blackbox(testarrayofstring.get(0));
    blackbox(testarrayofstring.get(1));
}

fn create_string_10(bench: &mut Bencher) {
    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
    let mut i = 0;
    bench.iter(|| {
        builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
        i += 1;
        if i == 10000 {
            builder.reset();
            i = 0;
        }
    });

    bench.bytes = 10;
}

fn create_string_100(bench: &mut Bencher) {
    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
    let s_owned = (0..99).map(|_| "x").collect::<String>();
    let s: &str = &s_owned;

    let mut i = 0;
    bench.iter(|| {
        builder.create_string(s); // zero-terminated -> 100 bytes
        i += 1;
        if i == 1000 {
            builder.reset();
            i = 0;
        }
    });

    bench.bytes = s.len() as u64;
}

fn create_byte_vector_100_naive(bench: &mut Bencher) {
    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
    let v: &[u8] = &v_owned;

    let mut i = 0;
    bench.iter(|| {
        builder.create_vector(v); // zero-terminated -> 100 bytes
        i += 1;
        if i == 10000 {
            builder.reset();
            i = 0;
        }
    });

    bench.bytes = v.len() as u64;
}

fn create_byte_vector_100_optimal(bench: &mut Bencher) {
    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
    let v: &[u8] = &v_owned;

    let mut i = 0;
    bench.iter(|| {
        builder.create_vector_direct(v);
        i += 1;
        if i == 10000 {
            builder.reset();
            i = 0;
        }
    });

    bench.bytes = v.len() as u64;
}

benchmark_group!(benches, create_byte_vector_100_naive, create_byte_vector_100_optimal, traverse_canonical_buffer, create_canonical_buffer_then_reset, create_string_10, create_string_100);
benchmark_main!(benches);
