package com.bonait.bnframework.common.helper;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;

/**
 * UDP 帮助类
 */
public class UdpHelper {
    //region 变量
    private static final String TAG = "UDP帮助";
    /**
     * 服务端口
     */
    public int ServerPort = 10000;
    /**
     * 是否启动监听
     */
    private volatile boolean isRuning = false;
    /**
     * 接收数据服务端
     */
    private DatagramSocket receiveSocket = null;
    /**
     * 反馈数据
     */
    public Handler myHandler = null;
    /**
     * 服务端
     */
    private ServerThread serverThread = new ServerThread();
    /**
     * 客户端
     */
    public ClientThread clientThread = new ClientThread();

    //endregion

    //region 外部调用

    /**
     * 服务启动监听
     *
     * @param port
     */
    public void Start(int port) {
        ServerPort = port;
        try {
            receiveSocket = new DatagramSocket(port);
        } catch (SocketException e) {
        }
        isRuning = true;
    }

    /**
     * 停止监听
     */
    public void Stop() {
        isRuning = false;
        if(receiveSocket!=null)
        {
            receiveSocket.close();
        }
    }

    /**
     * 发送数据
     *
     * @param ip
     * @param port
     * @param data
     */
    public void SendData(String ip, int port, String data) {
        Message msg = Message.obtain();
        msg.obj = new SendUdpMode(ip, port, data);
        msg.what = 1;
        clientThread.mhandler.sendMessage(msg);
    }
    //endregion

    //region 线程

    /**
     * 发送数据线程
     */
    public class ClientThread extends Thread {
        private Handler mhandler = null;

        @SuppressLint("HandlerLeak")
        @Override
        public void run() {
            Looper.prepare();
            mhandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    SendUdpMode message = (SendUdpMode) msg.obj;
                    byte[] data = message.data.getBytes(Charset.forName("GBK"));

                    DatagramPacket dpSend = null;
                    DatagramSocket sendSocket = null;
                    try {
                        InetAddress inetAddress = InetAddress.getByName(message.ip.toString().trim());
                        dpSend = new DatagramPacket(data, data.length, inetAddress, message.port);
                    } catch (UnknownHostException e) {
                    }
                    try {
                        double start = System.currentTimeMillis();
                        for (int i = 0; i < 1; i++) {
                            sendSocket = new DatagramSocket();
                            sendSocket.send(dpSend);
                            sendSocket.close();
                            Thread.sleep(80);
                            Log.i(TAG, "发送数据:  " + new String(data));
                        }
                        double end = System.currentTimeMillis();
                        double times = end - start;
                        Log.i(TAG, "发送数据所用时间: " + times + "ms");
                    } catch (IOException e) {
                        Log.i(TAG, "发送数据异常: " + e.getMessage());
                    } catch (InterruptedException e) {
                        Log.i(TAG, "发送数据异常: " + e.getMessage());
                    } finally {
                        if (sendSocket != null) {
                            sendSocket.close();
                        }
                    }
                }
            };
            Looper.loop();
        }
    }

    /**
     * 服务线程
     */
    private class ServerThread extends Thread {
        @Override
        public void run() {
            while (true) {
                if (isRuning) {
                    byte[] receiveData = new byte[1024];
                    DatagramPacket dpReceive = null;
                    dpReceive = new DatagramPacket(receiveData, receiveData.length);
                    try {
                        receiveSocket.receive(dpReceive);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    String recIp = dpReceive.getAddress().toString().substring(1);
                    String port = String.valueOf(dpReceive.getPort());
                    String content = "";
                    content = new String(receiveData, 0, dpReceive.getLength(), Charset.forName("GBK"));
                    if (dpReceive != null) {
                        Message revMessage = Message.obtain();
                        revMessage.what = 1;
                        revMessage.obj = "收到来自" + recIp + ":" + port + "的信息：" + content;
                        Log.i(TAG, "收到来自" + recIp + ":" + port + "的信息：" + content);
                        if (myHandler != null) {
                            myHandler.sendMessage(revMessage);
                        }
                    }
                }
            }
        }
    }
    //endregion

    //region 私有
    private static UdpHelper mInstance; //实例变量设置私有，防止直接通过类名访问

    public static synchronized UdpHelper getInstance() { //静态同步方法作为唯一的实例对象获取方式
        if (mInstance == null) {
            mInstance = new UdpHelper();
        }
        return mInstance;
    }

    private UdpHelper() { //默认构造函数私有，防止类外直接new创建对象
        clientThread.start();
        serverThread.start();
    }
    //endregion
}
