#if !AYCODE_NATIVEAOT
using AyCode.Core.Tests.TestModels;
using MessagePack;
using MessagePack.Resolvers;
using System.Runtime.CompilerServices;

namespace AyCode.Core.Benchmarks.Workloads.Scenarios;

/// <summary>
/// MessagePack benchmark, Byte[] I/O mode. Excluded from NativeAOT build because v3's StandardResolver
/// falls back to DynamicGenericResolver for closed-generic types (List&lt;TestOrderItem_All_True&gt; et al.),
/// which uses Activator.CreateInstance on formatter types the AOT trimmer drops →
/// MissingMethodException at runtime. Available for regular JIT runs (<c>dotnet run</c>) only.
/// </summary>
public sealed class MessagePackBenchmark<T> : ISerializerBenchmark where T : class
{
    private readonly T _order;
    private readonly MessagePackSerializerOptions _options;
    private readonly byte[] _serialized;

    public BenchmarkEngine Engine => BenchmarkEngine.MessagePack;
    public BenchmarkIoMode IoMode => BenchmarkIoMode.ByteArray;
    public BenchmarkDispatchMode DispatchMode => BenchmarkDispatchMode.SGen; // MessagePack uses [MessagePackObject] source-generated formatters (StandardResolver)
    public Type OrderType => typeof(T);
    public string OptionsPreset { get; }
    public int SerializedSize => _serialized.Length;
    public long SetupSerializeAllocBytes => 0;
    public long SetupDeserializeAllocBytes => 0;
    public string OptionsDescription { get; }

    public MessagePackBenchmark(T order, string optionsPreset)
    {
        _order = order;
        OptionsPreset = optionsPreset;

        //_options = ContractlessStandardResolver.Options.WithCompression(MessagePackCompression.None);
        //_options = ContractlessStandardResolver.Options.WithCompression(MessagePackCompression.Lz4Block);
        _options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None);

        var isContractless = _options.Resolver is ContractlessStandardResolver;
        OptionsDescription = $"Mode={( isContractless ? "Contractless" : "ContractBased")}, Compression={_options.Compression}";

        _serialized = MessagePackSerializer.Serialize(order, _options);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public void Serialize() => MessagePackSerializer.Serialize(_order, _options);

    [MethodImpl(MethodImplOptions.NoInlining)]
    public void Deserialize() => MessagePackSerializer.Deserialize<T>(_serialized, _options);

    public bool VerifyRoundTrip()
    {
        var bytes = MessagePackSerializer.Serialize(_order, _options);
        var roundTripped = MessagePackSerializer.Deserialize<T>(bytes, _options);
        return RoundTripValidator.DeepEqualsViaJson(_order, roundTripped);
    }
}
#endif
