using System;
using System.Runtime.CompilerServices;

namespace AyCode.Core.Serializers.Binaries;

/// <summary>
/// Binary input backed by a byte[] — the fastest input path.
/// Zero-copy: context references the byte[] directly, no linearization needed.
/// TryAdvanceSegment always returns false (single contiguous buffer).
///
/// Mirrors ArrayBinaryOutput pattern from the serializer side.
/// </summary>
public struct ArrayBinaryInput : IBinaryInputBase
{
    /// <summary>
    /// Single-buffer input — entire payload loaded upfront, no cross-segment advance needed.
    /// JIT-constant <c>true</c> → <c>BinaryDeserializationContext.EnsureAvailable</c> body is
    /// dead-code-eliminated for this specialization (per-read bounds-check overhead drops to ~0 ns).
    /// </summary>
    public static bool IsTrustedSingleSegment => true;

    private readonly byte[] _data;
    private readonly int _offset;
    private readonly int _length;

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ArrayBinaryInput(byte[] data, int offset, int length)
    {
        _data = data;
        _offset = offset;
        _length = length;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ArrayBinaryInput(byte[] data, int length) : this(data, 0, length) { }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public ArrayBinaryInput(byte[] data) : this(data, 0, data.Length) { }

    /// <summary>
    /// Provides the buffer directly — zero copy.
    /// Position starts at offset, bufferLength = offset + length.
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Initialize(out byte[] buffer, out int position, out int bufferLength)
    {
        buffer = _data;
        position = _offset;
        bufferLength = _offset + _length;
    }

    /// <summary>
    /// Single-buffer input — no more segments available.
    /// The JIT sees this always returns false and eliminates the call at the callsite.
    /// </summary>
    [MethodImpl(MethodImplOptions.NoInlining)]
    public bool TryAdvanceSegment(ref byte[] buffer, ref int position, ref int bufferLength, int needed)
        => false;

    /// <summary>
    /// No-op — ArrayBinaryInput has no rented buffers to release.
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void Release() { }
}
