#if !NETFX_CORE

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

namespace Plane.Communication
{
    public partial class UdpServerConnectionManager
    {
        private UdpClient _client = new UdpClient(5250);

        private object _receiveLock = new object();

        public void StartReceiving()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(UdpServerConnectionManager));
            }
            if (_shouldReceive && _isReceiving)
            {
                return;
            }
            _shouldReceive = true;
            Task.Factory.StartNew(() =>
            {
                lock (_receiveLock)
                {
                    _isReceiving = true;
                    IPEndPoint ep = null;
                    while (_shouldReceive)
                    {
                        try
                        {
                            var data = _client.Receive(ref ep);
                            var remoteAddress = ep.Address.ToString();
                            if (!_connections.ContainsKey(remoteAddress))
                            {
                                var connection = new UdpServerConnection(ep, _client.SendAsync);
                                _connections.Add(remoteAddress, connection);
                                RaiseConnectionEstablished(connection, remoteAddress);
                            }
                            _connections[remoteAddress].EnqueueDatagram(data);
                        }
                        catch (Exception ex)
                        {
                            RaiseExceptionThrown(ex);
                            Thread.Sleep(500);
                        }
                    }
                    _isReceiving = false;
                }
            }, TaskCreationOptions.LongRunning);
        }

        public void StopReceiving()
        {
            _shouldReceive = false;
        }

        private void DisposeCore()
        {
            _client.Close();
        }
    }
}

#endif
