using System.Buffers;
using System.Text;

namespace NATS.Server.Protocol;

public readonly struct ParsedCommandView
{
    public CommandType Type { get; init; }
    public string? Operation { get; init; }
    public ReadOnlyMemory<byte> Subject { get; init; }
    public ReadOnlyMemory<byte> ReplyTo { get; init; }
    public ReadOnlyMemory<byte> Queue { get; init; }
    public ReadOnlyMemory<byte> Sid { get; init; }
    public int MaxMessages { get; init; }
    public int HeaderSize { get; init; }
    public ReadOnlySequence<byte> Payload { get; init; }

    public static ParsedCommandView Simple(CommandType type, string operation) =>
        new() { Type = type, Operation = operation, MaxMessages = -1 };

    public ParsedCommand Materialize() =>
        new()
        {
            Type = Type,
            Operation = Operation,
            Subject = DecodeAsciiOrNull(Subject),
            ReplyTo = DecodeAsciiOrNull(ReplyTo),
            Queue = DecodeAsciiOrNull(Queue),
            Sid = DecodeAsciiOrNull(Sid),
            MaxMessages = MaxMessages,
            HeaderSize = HeaderSize,
            Payload = MaterializePayload(),
        };

    private ReadOnlyMemory<byte> MaterializePayload()
    {
        if (Payload.IsEmpty)
            return ReadOnlyMemory<byte>.Empty;

        return Payload.IsSingleSegment ? Payload.First : Payload.ToArray();
    }

    private static string? DecodeAsciiOrNull(ReadOnlyMemory<byte> value) =>
        value.IsEmpty ? null : Encoding.ASCII.GetString(value.Span);
}
