#region << 版 本 注 释 >>

/*--------------------------------------------------------------------
* 版权所有 (c) 2026 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：Mr.Wen's MacBook Pro
* 命名空间：Sln.IntelliBelt.Socket
* 唯一标识：E0B382FE-A373-4B1C-9175-EC962B22F6A5
*
* 创建者：WenJY
* 电子邮箱：
* 创建时间：2026-04-24 10:48:20
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System.Collections.Concurrent;
using System.Text;
using Sln.IntelliBelt.Common;
using Sln.IntelliBelt.Serilog;
using Sln.IntelliBelt.Socket.Adapter;
using TouchSocket.Core;
using TouchSocket.Sockets;

namespace Sln.IntelliBelt.Socket;

public class TcpServer
{
    private readonly SerilogHelper _logger;

    private readonly TcpService _service;

    private readonly StringChange _stringChange;
    
    public TcpServer(SerilogHelper logger, TcpService service, StringChange stringChange)
    {
        _logger = logger;
        _service = service;
        _stringChange = stringChange;
    }

    public delegate void ReceivedClientBuffer(byte[] buffer);
    public event ReceivedClientBuffer? ReceivedClientBufferEvent;

    public delegate void RefreshClientInfo(TcpService tcpService);
    public event RefreshClientInfo? RefreshClientInfoEvent;

    public delegate void ReceivedBufferRequestInfo(TcpSessionClient client,BufferRequestInfo requestInfo);
    public event ReceivedBufferRequestInfo ReceivedBufferRequestInfoEvent;

    public void Init(int serverPort)
        {
            try
            {
                _service.Connecting = (client, e) => {
                    
                    return EasyTask.CompletedTask;
                };
                _service.Connected = (client, e) => {
                    _logger.Info($"客户端{client.IP}:{client.Port}接入服务成功,Id:{client.Id}");
                    RefreshClientInfoEvent?.Invoke(_service);
                    return EasyTask.CompletedTask;
                };
                _service.Closed = (client, e) => {
                    _logger.Info($"客户端{client.IP}:{client.Port}断开连接");
                    RefreshClientInfoEvent?.Invoke(_service);
                    return EasyTask.CompletedTask;
                };
                _service.Received = (client, e) =>
                {
                    if (e.RequestInfo is BufferRequestInfo request)
                    {
                        string msg = $"{client.Id}链接收到终端:{request.terminalAddr}指令====>>>>ContentLen:{request.contentLen};Content:{request.content};";
                        _logger.Info($"{msg}");
                        ReceivedBufferRequestInfoEvent?.Invoke(client, request);
                    }
                
                    return EasyTask.CompletedTask;
                };
                
                _service.SetupAsync(new TouchSocketConfig()//载入配置
                    .SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:{serverPort}") })
                    .SetTcpDataHandlingAdapter(() => new CustomDataHandlingAdapter(_logger,_stringChange))
                    .ConfigureContainer(a =>//容器的配置顺序应该在最前面
                    {
                        a.AddConsoleLogger();
                    })
                    .ConfigurePlugins(a =>
                    {
                        //自定义插件
                    }));
                _service.StartAsync();
               
                _logger.Info($"TcpServer启动成功，监听端口：{serverPort}");
            }
            catch (Exception ex)
            {
                _logger.Info($"TcpServer启动异常：{ex.Message}");
            }

        }

    /// <summary>
    /// 向指定客户端发送指令，使用序号关联匹配应答，避免创建新的 TCP 连接
    /// </summary>
    public async Task<BufferRequestInfo> SendMsgToClient(string clientId, byte[] buffer)
    {
        if (_service.Clients.TryGetClient(clientId, out TcpSessionClient tcpSessionClient))
        {
            var waitClinet = tcpSessionClient.CreateWaitingClient(new WaitingOptions()
            {
                FilterFunc = response => //设置用于筛选的fun委托，当返回为true时，才会响应返回
                {
                    return true;
                }
            });
            Task<ResponsedData> responsedData = waitClinet.SendThenResponseAsync(buffer, 5000);
            IRequestInfo requestInfo = responsedData.Result.RequestInfo;
                    
            BufferRequestInfo bufferRequestInfo = (BufferRequestInfo)requestInfo ;
                
            return bufferRequestInfo;
        }
        else
        {
            return new BufferRequestInfo();
        }
    }
}