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

namespace Rokid.MRC
{
    public class Define
    {
        public const int UTP_BroadPort = 8635;

        //ServerPort前后端不一致也没关系
        public const int UDP_MultiServerPort = 8630;

        //ClientPort就是前后端统一的发送和接收端口，必须一致
        public const int UDP_MultiClientPort = 8640;

        //多播组必须一致
        public const string UDP_MultiCastIP = "239.0.0.1";
    }

    //服务端广播消息
    public class UDPServer
    {
        private string castMsg = null;
        private byte[] sendData;

        private static IPEndPoint iPEndPoint;
        private static Socket socket;
        private Thread thread;

        public bool StopBroadcast = false;

        public int castInterval = 2000;

        public void Init(bool broadCast)
        {
            //创建发送数据
            castMsg = SDKManager.Instance.GetDeviceName();
            sendData = Encoding.ASCII.GetBytes(castMsg);

            StopBroadcast = false;

            if(broadCast)
            {
                BroadcastWithSocket();

                //BroadCastWithUDPClient();
            }
            else
            {
                MultiCast();
            }
        }

        public void OnDestroy()
        {
            StopBroadcast = true;
        }

        //创建UdpClient对象
        public UdpClient broadUdp = new UdpClient();
        public Thread broadCastThread;
        public void BroadCastWithUDPClient()
        {
            //调用UdpClient对象的Connect方法建立默认远程主机
            //127.0.0.1是回环地址，用于测试本机内连接
            // udp.Connect("127.0.0.1", 888);
            //192.168.1.255用来发到其他的主机上
            broadUdp.Connect("10.91.8.255", Define.UTP_BroadPort);
            broadCastThread = new Thread(() =>
            {
                while(true)
                {
                    try
                    {
                        if(StopBroadcast)
                            break;

                        ////定义一个字节数组，用来存放发送到远程主机的信息
                        //Byte[] sendBytes = Encoding.Default.GetBytes("(" + DateTime.Now.ToLongTimeString() + ")节目预报：八点有大型晚会，请收听");
                        //Debug.Log("(" + DateTime.Now.ToLongTimeString() + ")节目预报：八点有大型晚会，请收听");
                        ////调用UdpClient对象的Send方法将UDP数据报发送到远程主机
                        //udp.Send(sendBytes, sendBytes.Length);

                        broadUdp.Send(sendData, sendData.Length);

                        Debug.Log(GetType() + " BroadCastWithUDPClient IP：" + castMsg);

                        Thread.Sleep(castInterval);//线程休眠2秒
                    }
                    catch(Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }

                broadUdp.Close();

                if(broadCastThread.ThreadState == ThreadState.Running)
                {
                    Debug.Log(GetType() + " BroadCastWithUDPClient UDP Thread Closed");
                    broadCastThread.Abort();
                }
            });

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

        //要通过其进行通信的本地端口号
        private UdpClient multiUdp = new UdpClient(Define.UDP_MultiServerPort);
        private Thread multiThread;
        private void MultiCast()
        {
            //将UdpClient添加到多播组
            IPAddress addr = IPAddress.Parse(Define.UDP_MultiCastIP);
            multiUdp.JoinMulticastGroup(addr);

            //目的地的IP地址和端口号
            IPEndPoint multicast = new IPEndPoint(IPAddress.Parse(Define.UDP_MultiCastIP), Define.UDP_MultiClientPort);

            Debug.Log(GetType() + " MultiCast Local IP：" + multiUdp.Client.LocalEndPoint.ToString());

            multiThread = new Thread(() =>
            {
                while(true)
                {
                    try
                    {
                        if(StopBroadcast)
                        {
                            break;
                        }

                        //调用UdpClient对象的Send方法将UDP数据报发送到位于指定远程终结点的主机
                        multiUdp.Send(sendData, sendData.Length, multicast);

                        //Debug.Log(GetType() + " MultiCast Msg：" + castMsg);

                        Thread.Sleep(castInterval);
                    }
                    catch(Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }

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

                multiUdp.Close();

                if(multiThread.ThreadState == ThreadState.Running)
                {
                    Debug.Log(GetType() + " MultiCast UDP Thread Closed");
                    multiThread.Abort();
                }
            });

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

        //开启线程，持续广播自己的IP地址
        private void BroadcastWithSocket()
        {
            iPEndPoint = new IPEndPoint(IPAddress.Broadcast, Define.UTP_BroadPort);

            Debug.Log(iPEndPoint.AddressFamily);

            socket = new Socket(iPEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);

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

            thread = new Thread(() =>
            {
                while(true)
                {
                    if(StopBroadcast)
                        break;

                    Debug.Log(GetType() + " BroadcastWithSocket IP：" + castMsg);

                    socket.SendTo(sendData, iPEndPoint);

                    //暂停几秒再发送
                    Thread.Sleep(castInterval);
                }

                socket.Close();

                if(thread.ThreadState == ThreadState.Running)
                {
                    Debug.Log(GetType() + " BroadcastWithSocket UDP Thread Closed");
                    thread.Abort();
                }
            });

            thread.Start();
        }

    }
}