using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
#if NETSTANDARD2_0_OR_GREATER || NET5_0_OR_GREATER
namespace System.Net.Sockets.Kcp.Simple
{
    /// 
    /// 简单例子
    /// 
    public class SimpleKcpClient : IKcpCallback
    {
        UdpClient client;
        public SimpleKcpClient(int port)
            : this(port, null)
        {
        }
        public SimpleKcpClient(int port, IPEndPoint endPoint)
        {
            client = new UdpClient(port);
            kcp = new SimpleSegManager.Kcp(2001, this);
            this.EndPoint = endPoint;
            BeginRecv();
        }
        public SimpleSegManager.Kcp kcp { get; }
        public IPEndPoint EndPoint { get; set; }
        public void Output(IMemoryOwner buffer, int avalidLength)
        {
            var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray();
            client.SendAsync(s, s.Length, EndPoint);
            buffer.Dispose();
        }
        public async void SendAsync(byte[] datagram, int bytes)
        {
            kcp.Send(datagram.AsSpan().Slice(0, bytes));
        }
        public async ValueTask ReceiveAsync()
        {
            var (buffer, avalidLength) = kcp.TryRecv();
            while (buffer == null)
            {
                await Task.Delay(10);
                (buffer, avalidLength) = kcp.TryRecv();
            }
            var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray();
            return s;
        }
        private async void BeginRecv()
        {
            var res = await client.ReceiveAsync();
            EndPoint = res.RemoteEndPoint;
            kcp.Input(res.Buffer);
            BeginRecv();
        }
    }
}
#endif