namespace AyCode.Core.Serializers.Console.Benchmarks;
///
/// Common contract for every per-engine, per-I/O-mode benchmark row. Each implementation captures
/// one (Engine × IoMode × OptionsPreset) combination — e.g. AcBinary Byte[] FastMode SGen —
/// and exposes a uniform Serialize / Deserialize hot-path that the benchmark loop
/// drives through warmup + adaptive-iter calibration + measurement.
///
/// The default + methods iterate
/// the hot path N times — overrides are only needed when an implementor wants Ser/Des-specific
/// warmup state (rare). Round-trip-only benchmarks (NamedPipe etc.) set
/// to true so the bench loop skips the Des-phase and routes timing into the RT columns.
///
internal interface ISerializerBenchmark
{
/// Serializer engine — e.g. "AcBinary", "MemoryPack", "MessagePack".
string Engine { get; }
/// I/O mode — e.g. "Byte[]", "BufWr reuse", "BufWr new", "NamedPipe", "FileStream".
string IoMode { get; }
/// Dispatch mode — "SGen", "Runtime", or "Hybrid". For AcBinary derived from UseGeneratedCode + child-type SGen coverage; non-AcBinary engines report their own native dispatch model.
string DispatchMode { get; }
/// Options preset name — e.g. "FastMode", "Default", "NoIntern", "WithCompression".
string OptionsPreset { get; }
/// Synthesized display name from Engine + IoMode + OptionsPreset.
string Name => $"{Engine} ({IoMode}, {OptionsPreset})";
int SerializedSize { get; }
string? OptionsDescription => null;
/// One-time SERIALIZER-side setup allocation cost (e.g., pre-allocated ArrayBufferWriter with internal buffer). Captured in constructor; 0 for byte[] API and Fresh-BufWriter variants.
long SetupSerializeAllocBytes { get; }
/// One-time DESERIALIZER-side setup allocation cost (e.g., long-lived AsyncPipeReaderInput's ArrayPool rent + ManualResetEventSlim, drain-task scaffolding). Captured in constructor; 0 for byte[] API and any setup-free deserialize path.
long SetupDeserializeAllocBytes { get; }
/// True when Serialize() does a full round-trip (e.g. NamedPipe) and Deserialize() is a no-op.
/// Used by the SUMMARY: WINNERS section to skip such cells from "Fastest Serialize" and "Fastest Deserialize"
/// rankings (because both metrics are misleading there) — they still participate in "Fastest Round-trip".
/// Default false for in-memory IO modes which measure Ser and Des separately.
bool IsRoundTripOnly => false;
/// Warm only the Serialize path. Default body iterates N times.
/// Overrides are only needed when the implementor wants Ser-specific warmup-state (e.g. pre-allocate buffers).
/// On benchmarks (NamedPipe-style) performs the full RT,
/// so this warms the entire round-trip path.
void WarmupSerialize(int iterations)
{
for (var i = 0; i < iterations; i++) Serialize();
}
/// Warm only the Deserialize path. Default body iterates N times.
/// On benchmarks is a no-op, so the bench loop
/// skips the Des-phase entirely for those cells.
void WarmupDeserialize(int iterations)
{
for (var i = 0; i < iterations; i++) Deserialize();
}
void Serialize();
void Deserialize();
/// Round-trip correctness check — called once per cell before warmup. Returns true if Serialize+Deserialize preserves data.
bool VerifyRoundTrip();
}