using System.Runtime.CompilerServices;

namespace AyCode.Core.Serializers.Binaries;

/// <summary>
/// Interface for source-generated binary property writers.
/// Implementations bypass the runtime switch/delegate property loop in WriteObject.
/// Each generated writer handles all properties of a specific type using direct obj.Property access.
/// 
/// Performance gains over runtime path:
/// - No Func&lt;&gt;.Invoke() delegate calls (~5-8ns/property saved)
/// - No switch dispatch (~2-3ns/property saved)
/// - No boxing for value type properties
/// - Small per-type code (~300B) vs 27KB monolithic WriteObject — better ICache behavior
/// </summary>
internal interface IGeneratedBinaryWriter
{
    /// <summary>
    /// Writes all properties of the given object to the serialization context.
    /// Called from WriteObject when a generated writer is available for the type.
    /// The implementation uses direct property access (obj.Id, obj.Name, etc.) instead of delegates.
    /// </summary>
    /// <param name="value">The object whose properties to write. Implementation casts to the concrete type.</param>
    /// <param name="context">The serialization context (owns buffer, position, options).</param>
    /// <typeparam name="TOutput">Output strategy (ArrayBinaryOutput or BufferWriterBinaryOutput).</typeparam>
    void WriteProperties<TOutput>(object value, AcBinarySerializer.BinarySerializationContext<TOutput> context)
        where TOutput : struct, IBinaryOutputBase;

    /// <summary>
    /// Full scan pass for this type: null/depth check, ref tracking (slot-based IdentityMap),
    /// and recursive property scan (strings + complex types).
    /// Replaces the entire runtime ScanValue for SGen types — no GetWrapper, no delegate invoke.
    /// Called from ScanForDuplicates or from parent SGen ScanObject (child).
    /// </summary>
    void ScanObject<TOutput>(object value, AcBinarySerializer.BinarySerializationContext<TOutput> context)
        where TOutput : struct, IBinaryOutputBase;

    /// <summary>
    /// SGen scan pass entry point. Called from Serialize instead of runtime ScanForDuplicates.
    /// HasCaching check + ScanObject + SortWritePlan — eliminates GetWrapper for the root type.
    /// </summary>
    void ScanForDuplicates<TOutput>(object value, AcBinarySerializer.BinarySerializationContext<TOutput> context)
        where TOutput : struct, IBinaryOutputBase;
}
