using System.Buffers;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using AyCode.Core.Serializers.Binaries;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.Logging;
namespace AyCode.Services.SignalRs;
///
/// Custom SignalR hub protocol using AcBinarySerializer for wire format.
/// Eliminates JSON+Base64 overhead by serializing all HubMessages directly to binary.
///
/// Wire format per message:
/// [4 bytes: payload length (little-endian)] [payload bytes]
///
/// Payload structure:
/// [1 byte: message type] [message-specific fields serialized via AcBinary]
///
/// Message types map 1:1 to SignalR HubMessageType values.
/// Arguments are serialized individually with an INT32 length prefix each,
/// enabling deferred deserialization via IHubProtocol's binder pattern.
///
/// Write path: BufferWriterBinaryOutput for zero virtual dispatch on the hot path.
/// Argument payloads serialized directly to the pipe via AcBinarySerializer (zero-copy write).
///
/// Read path: SequenceReader<byte> reads directly from the pipe's ReadOnlySequence.
/// Argument deserialization uses the pipe's backing byte[] via TryGetArray (zero-copy read).
///
public class AcBinaryHubProtocol : IHubProtocol
{
private const int LengthPrefixSize = 4;
// Message type markers (matching HubMessageType enum values)
private const byte MsgInvocation = 1;
private const byte MsgStreamItem = 2;
private const byte MsgCompletion = 3;
private const byte MsgStreamInvocation = 4;
private const byte MsgCancelInvocation = 5;
private const byte MsgPing = 6;
private const byte MsgClose = 7;
private const byte MsgAck = 8;
private const byte MsgSequence = 9;
// Chunked protocol framing for AsyncSegment mode
private const byte MsgAsyncChunkStart = 200;
private const byte MsgAsyncChunkData = 201;
private const byte MsgAsyncChunkEnd = 202;
/// Sentinel object placed in the args array for the streamed argument (replaced after chunk deserialization).
protected static readonly object StreamedArgPlaceholder = new();
protected volatile AcBinarySerializerOptions _options;
protected readonly BinaryProtocolMode _protocolMode;
protected readonly ILogger? _logger;
/// Per-connection chunk accumulation state. Key is IInvocationBinder (per-connection, GC-friendly).
private readonly ConditionalWeakTable? _chunkStates;
private sealed class AsyncChunkState
{
public HubMessage PartialMessage = null!;
public object?[] Args = null!;
public int StreamedArgIndex;
public Type StreamedArgType = null!;
public Pipe InternalPipe = null!;
public Task