using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
using UnityEngine;

namespace Rokid.MRC
{
    //客户端，接收服务器的广播的IP消息
    public class UDPClient
    {
        private byte[] recvData;
        private int recvSize;

        private Socket sock;
        private Thread thread;

        //接收到服务端的IP后，触发
        public Action<string> onReceived;

        public void Init(bool broadCast)
        {
            if(broadCast)
            {
                StartBroadCast();
            }
            else
            {
                StartMultiCast();
            }
        }

        public void OnDestroy()
        {
            StopBroadCast();

            StopMultiCast();
        }

        //获取服务器IP
        public void StartBroadCast()
        {
            Debug.Log("Client BroadCast");

            try
            {
                if(sock != null)
                    StopBroadCast();

                thread = new Thread(() =>
                {
                    sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    IPEndPoint iep = new IPEndPoint(IPAddress.Any, Define.UTP_BroadPort);
                    sock.Bind(iep);
                    EndPoint ep = (EndPoint)iep;

                    recvData = new byte[1024];

                    Debug.Log(sock.EnableBroadcast);
                    sock.EnableBroadcast = true;

                    while(true)
                    {
                        recvSize = sock.ReceiveFrom(recvData, ref ep);

                        string ip = ep.ToString().Split(':')[0];

                        Debug.Log("Client BroadCast ： Server IPEndPoint " + ep.ToString());
                        Debug.Log("Client BroadCast ： Server IP " + ip);

                        //解析收到的数据，一串服务端的IP地址，未做粘包、拆包处理
                        string str = Encoding.ASCII.GetString(recvData, 0, recvSize);

                        if(onReceived != null)
                            onReceived(ip);

                        Debug.Log("Client BroadCast ： Received " + str);
                    }
                });

                thread.Start();
            }
            catch(Exception e)
            {
                Debug.LogError("Client BroadCast StartListen Error ：" + e.Message);
            }
        }

        //关闭服务器
        public void StopBroadCast()
        {
            if(sock != null)
            {
                sock.Close();
                sock = null;
            }

            recvData = null;

            if(thread != null)
            {
                thread.Abort();
            }
        }

        //定义一个bool变量，标识是否接收数据
        private bool flag = true;
        private Thread multiThread;
        private UdpClient multiUdp;
        private IPAddress addr;
        private void StartMultiCast()
        {
            Debug.Log("Client MultiCast");

            //使用端口号实例化UDP连接对象
            multiUdp = new UdpClient(Define.UDP_MultiClientPort);

            addr = IPAddress.Parse(Define.UDP_MultiCastIP);
            multiUdp.JoinMulticastGroup(addr);

            //创建IPEndPoint对象，用来显示响应主机的标识
            IPEndPoint ipendpoint = new IPEndPoint(addr, Define.UDP_MultiServerPort);

            flag = true;

            multiThread = new Thread(() =>
            {
                while(flag)
                {
                    try
                    {
                        //判断是否有网络数据
                        if(multiUdp.Available <= 0)
                            continue;

                        if(multiUdp.Client == null)
                            return;

                        //从远程主机返回的UDP数据报
                        byte[] bytes = multiUdp.Receive(ref ipendpoint);

                        string ip = ipendpoint.ToString().Split(':')[0];

                        Debug.Log("Client MultiCast ： Server IPEndPoint " + ipendpoint.ToString());
                        Debug.Log("Client MultiCast ： Server IP " + ip);

                        //将获得的UDP数据报转换为字符串形式
                        string str = Encoding.Default.GetString(bytes);

                        if(onReceived != null)
                            onReceived(ip);

                        Debug.Log("Client MultiCast : Received " + str);
                    }
                    catch(Exception ex)
                    {
                        Debug.Log(ex.Message);
                    }

                    Thread.Sleep(2000);
                }

                StopMultiCast();
            });

            multiThread.Start();//启动线程
        }

        private void StopMultiCast()
        {
            //不接收数据
            flag = false;

            if(multiThread != null)
            {
                if(multiThread.ThreadState == ThreadState.Running)
                    multiThread.Abort();
            }

            //if(addr != null)
            //{
            //    multiUdp?.DropMulticastGroup(addr);
            //    addr = null;
            //}

            multiUdp?.Close();
        }
    }
}