namespace AyCode.Core.Serializers.Binaries;

/// <summary>
/// Interface for source-generated binary property readers.
/// Implementations bypass the runtime property loop, wrapper lookup, and delegate-based setters.
/// Each generated reader handles all properties of a specific type using direct property access.
///
/// Performance gains over runtime path:
/// - No GetWrapper() dictionary lookup per object (~20-50ns saved)
/// - No property setter delegate calls (~5-8ns/property saved)
/// - No AccessorType switch dispatch (~2-3ns/property saved)
/// - No boxing for value type properties (direct obj.Prop = context.ReadXxx())
/// - No ReadValue dispatch table for known property types
/// </summary>
internal interface IGeneratedBinaryReader
{
    /// <summary>
    /// Creates a new instance and reads all properties from the stream.
    /// Handles both markerless (no UseMetadata) and markered wire formats.
    /// UseMetadata=true falls back to runtime path (cross-type CacheMap not known at compile time).
    /// </summary>
    /// <param name="context">The deserialization context (owns buffer, position, options).</param>
    /// <param name="cacheIndex">-1 = not cached, 0+ = register at this cache index for ref tracking.</param>
    /// <typeparam name="TInput">Input strategy (ArrayBinaryInput or SequenceBinaryInput).</typeparam>
    /// <returns>The deserialized object, or null if creation failed.</returns>
    object? ReadObject<TInput>(AcBinaryDeserializer.BinaryDeserializationContext<TInput> context, int cacheIndex)
        where TInput : struct, IBinaryInputBase;

    /// <summary>
    /// Reads all properties into an existing instance (no object creation, no cache registration).
    /// Called from parent SGen reader after instance creation + cache registration.
    /// Mirrors WriteProperties: parent handles lifecycle, child handles data.
    /// </summary>
    /// <param name="value">The pre-created instance to populate. Implementation casts to the concrete type.</param>
    /// <param name="context">The deserialization context (owns buffer, position, options).</param>
    /// <typeparam name="TInput">Input strategy (ArrayBinaryInput or SequenceBinaryInput).</typeparam>
    void ReadProperties<TInput>(object value, AcBinaryDeserializer.BinaryDeserializationContext<TInput> context)
        where TInput : struct, IBinaryInputBase;
}
