using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RobotLib
{
    public class Com
    {
        private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
        private UdpClient udpClient;
        private Thread thread;

        public event EventHandler<MessageEventArgs> MessageReveived;

        public Com()
        {
        }

        public Com(string host, int port)
        {
            Connect(host, port);
        }

        public bool IsConnected { get; private set; }


        public void Connect(string host, int port)
        {
            if (!IsConnected)
            {
                udpClient = new UdpClient();
                udpClient.Connect(host, port);
                IsConnected = true;

                thread = new Thread(Run);
                thread.IsBackground = true;
                thread.Start();
            }
        }

        public void Disconnect()
        {
            IsConnected = false;
            if (thread != null)
            {
                thread.Interrupt();
                thread.Join();
            }
        }

        public void Run()
        {
            while(IsConnected)
            {
                try
                {
                    IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
                    byte[] dataReceived = udpClient.Receive(ref remote);
                    string msg = Encoding.ASCII.GetString(dataReceived);
                    log.Trace($"Msg received from {remote}: {msg}");
                    MessageReveived?.Invoke(this, new MessageEventArgs(msg));
                }
                catch (ThreadInterruptedException)
                {
                    return;
                }
                catch (Exception ex) 
                { 
                    log.Fatal(ex, "Exception in Receiver-Thread\r\n" + ex); 
                }
            }
        }

        public void SendMsg(string msg)
        {
            byte[] data = Encoding.ASCII.GetBytes(msg);
            udpClient.Send(data, data.Length);
            log.Trace($"Msg sent to {udpClient.Client.RemoteEndPoint}: {msg}");
        }

    }
}
