/**
 * Micro-bench: repeated LE binary write+read roundtrip (same primitives as wire_roundtrip_test).
 * Prints one JSON line to stdout for benchmarks/cpp-wire-micro-bench.js
 */
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

#include "binary_reader.h"
#include "binary_writer.h"

using deukpack::BinaryReader;
using deukpack::BinaryWriter;
using deukpack::Endianness;

static void one_binary_le_roundtrip()
{
    BinaryWriter w(Endianness::Little);
    w.WriteByte(0xab);
    w.WriteI16(-1000);
    w.WriteI32(-42);
    w.WriteI64(static_cast<int64_t>(0x123456789abcdefLL));
    w.WriteDouble(3.141592653589793);
    w.WriteString("hello-deukpack");
    std::vector<uint8_t> bin = {1, 2, 3, 255};
    w.WriteBinary(bin);

    std::vector<uint8_t> buf = w.GetBuffer();
    BinaryReader r(buf.data(), buf.size(), Endianness::Little);

    (void)r.ReadByte();
    (void)r.ReadI16();
    (void)r.ReadI32();
    (void)r.ReadI64();
    (void)r.ReadDouble();
    (void)r.ReadString();
    (void)r.ReadBinary();
}

int main(int argc, char **argv)
{
    uint64_t n = 100000;
    if (argc > 1)
    {
        n = std::strtoull(argv[1], nullptr, 10);
        if (n == 0)
            n = 100000;
    }

    auto t0 = std::chrono::steady_clock::now();
    for (uint64_t i = 0; i < n; ++i)
    {
        one_binary_le_roundtrip();
    }
    auto t1 = std::chrono::steady_clock::now();
    const double totalMs = std::chrono::duration<double, std::milli>(t1 - t0).count();

    std::cout << "{\"runtime\":\"cpp\",\"measureKind\":\"wire_primitive_le_roundtrip\",\"iterations\":" << n
              << ",\"totalMs\":" << totalMs << ",\"avgMs\":" << (totalMs / static_cast<double>(n)) << "}\n";
    return 0;
}
