﻿using System;
using DarkRift;

// Disable things we cannot do in a Unity context
// ReSharper disable UseStringInterpolation
// ReSharper disable UseNameofExpression

namespace Dissonance.Integrations.DarkRift2
{
    public class DarkRift2Helpers
    {
        /// <summary>
        /// This is the tag that Dissonance uses for DarkRift messages.
        /// 
        /// If this value is already in use in your game change this value. Make sure to recompile the server DLL!
        /// </summary>
        public const ushort DissonanceMessageTag = 33652;

        public static ArraySegment<byte>? ReadPacket([NotNull] Message message, byte[] buffer)
        {
            if (message == null)
                throw new ArgumentNullException("message");

            //Early exit if this message isn't for us
            if (message.Tag != DissonanceMessageTag)
                return null;

            using (var reader = message.GetReader())
            {
                //Read the 16 bit length prefix
                var length = reader.ReadUInt16();
                if (length > buffer.Length)
                    throw new ArgumentException("Output buffer is too small");

                //Read the raw data
                //reader.ReadRawInto(buffer, 0, length); <-- this variant should be slightly faster, but it seems to be broken in the current DR2 version.
                for (var i = 0; i < length; i++) buffer[i] = reader.ReadByte();
                
                //Return the slice of the buffer which contains the packet data
                return new ArraySegment<byte>(buffer, 0, length);
            }
        }

        [NotNull] public static DarkRiftWriter WritePacket(ArraySegment<byte> packet)
        {
            if (packet.Count > ushort.MaxValue)
                throw new ArgumentException(string.Format("Attempted to send oversize packet ({0} bytes)", packet.Count));

            var writer = DarkRiftWriter.Create(packet.Count + sizeof(ushort));

            //Write 16 bit length prefix
            writer.Write((ushort)packet.Count);

            //Write the packet data
            writer.WriteRaw(packet.Array, packet.Offset, packet.Count);

            return writer;
        }
    }
}
