using ProjectManagementSystem.Device.Extenions;
using RRQMCore;
using RRQMCore.ByteManager;
using RRQMSocket;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace ProjectManagementSystem.Device.Core
{
    public class CommunicationTcp : CommunicationBase, ICommunication
    {
        public bool IsStart { get { return tcpService?.ServerState == ServerState.Running; } }

        protected string ipHost;
        protected TcpService tcpService;

        public CommunicationTcp(string ipAddress, int port)
        {
            ipHost = $"{ipAddress}:{port}";
        }

        public void Start()
        {
            tcpService = new TcpService();
            tcpService.Logger = new LogerBox(this.LogMsg);

            //订阅事件
            tcpService.Connecting += (client, e) =>
            {
                e.DataHandlingAdapter = new NormalDataHandlingAdapter();
            };

            tcpService.Connected += (client, e) => 
            { 
                LogMsg($"客户端{client.IP}:{client.Port}已连接，总连接数:{tcpService.SocketClients.Count}");
            };

            tcpService.Disconnected += (client, e) => 
            {
                LogMsg($"客户端{client.IP}:{client.Port}已断开，总连接数:{tcpService.SocketClients.Count}");
            };

            tcpService.Received += OnReceived;
            
            ////声明配置
            var config = new RRQMConfig();
            config.SetListenIPHosts(new IPHost[] { new IPHost(ipHost) });
            config.SetClearInterval(-1);

            //载入配置                                                       
            tcpService.Setup(config);

            try
            {
                //启动
                tcpService.Start();
                LogMsg($"TCP服务端{ipHost}已启动");

                var address = Dns.GetHostAddresses(Dns.GetHostName()).FirstOrDefault(d => ipHost.Contains(d.ToString()));
                if (address == null)
                {
                    LogMsg($"注意：TCP监听IP不属于本机IP");
                }
            }
            catch (Exception ex)
            {
                LogMsg($"TCP服务端{ipHost}启动异常", ex);
                Stop();
            }

        }

        public void Stop()
        {
            if (this.tcpService != null)
            {
                this.tcpService.Stop();
            }
        }

        public IEnumerable<string> GetClientIDs()
        {
            return tcpService.SocketClients.GetIDs();
        }

        public void SendCommand(byte[] data, string address)
        {
            var clients = tcpService.GetClients();
            for (int i = 0; i < clients.Length; i++)
            {
                var client = clients[i];

                if (client.Online)
                {
                    string clientName = client.MainSocket.RemoteEndPoint.ToString();

                    if (address == "127.0.0.1"
                        || string.IsNullOrEmpty(address)
                        || clientName.StartsWith(address))
                    {
                        try
                        {
                            client.Send(data);
                            LogMsg($"{clientName}: Send: {data.Byte2HexString()}");
                        }
                        catch (Exception ex)
                        {
                            LogMsg($"{clientName}: SendErr: {data.Byte2HexString()}", ex);
                        }
                    }
                }
            }
        }

        private void OnReceived(SocketClient client, ByteBlock byteBlock, IRequestInfo obj)
        {
            byte[] data = new byte[byteBlock.Length];
            Buffer.BlockCopy(byteBlock.Buffer, 0, data, 0, data.Length);

            string clientName = client.MainSocket.RemoteEndPoint.ToString();
            LogMsg($"{clientName}: Recv: {data.Byte2HexString()}");

            DataReceived?.Invoke(clientName, data);
        }
    }
}
