#region << 版 本 注 释 >>

/*--------------------------------------------------------------------
* 版权所有 (c) 2026 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：Mr.Wen's MacBook Pro
* 命名空间：Sln.IntelliBelt.Socket.Adapter
* 唯一标识：B09DFB64-3AE1-4CD4-A3A3-478B6EF97A48
*
* 创建者：WenJY
* 电子邮箱：
* 创建时间：2026-04-24 10:58:37
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System.Buffers;
using System.Data;
using System.Text;
using Sln.IntelliBelt.Common;
using Sln.IntelliBelt.Config;
using Sln.IntelliBelt.Serilog;
using TouchSocket.Core;
using Exception = System.Exception;

namespace Sln.IntelliBelt.Socket.Adapter;

public class CustomDataHandlingAdapter:CustomDataHandlingAdapter<BufferRequestInfo>
{
    
    private readonly SerilogHelper _logger;
    private readonly StringChange _stringChange;

    public CustomDataHandlingAdapter(SerilogHelper logger, StringChange stringChange)
    {
        _logger = logger;
        _stringChange = stringChange;
    }
    
    protected override FilterResult Filter<TReader>(ref TReader reader, bool beCached, ref BufferRequestInfo request)
    {
        CacheTimeoutEnable = true;
        CacheTimeout = new TimeSpan(0, 0, 0, 0, 5000);
        
        //ByteBlock byteBlock = new ByteBlock(reader.Sequence.ToArray());
        
        try
        {
            if (reader.BytesRemaining < 5)
            {
                reader.BytesRead = 0;
                return FilterResult.Cache;
            }
        
            byte[] buffer = reader.Sequence.ToArray();
        
            _logger.Info($"收到终端指令:{_stringChange.bytesToHexStr(buffer,buffer.Length)}");
            //读取帧头
            byte headerByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取终端类型
            byte terminalTypeByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取终端地址
            byte[] terminalAddressBytes = reader.GetSpan(2).ToArray();
            reader.Advance(2);
            string terminalAddrStr = _stringChange.ConverToString(terminalAddressBytes); 
            
            //读取指令序号
            byte serialNumberByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取功能标识码
            byte identCodeByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取对象类别
            byte objTypeByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取数据内容的数据长度
            int contentLen = (int)reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取数据内容
            byte[] contentBytes = reader.GetSpan(contentLen).ToArray();
            reader.Advance(contentLen);
            string contentStr = _stringChange.ConverToString(contentBytes);
            
            //读取 CS 校验
            byte checksumByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //读取帧尾
            byte tailByte = reader.GetSpan(1).ToArray()[0];
            reader.Advance(1);
            
            //Byte[] checkBitBytes = new Byte[buffer.Length - 2];
            Byte[] checkBitBytes = new Byte[contentLen + 8];
            Array.Copy(buffer, 0, checkBitBytes, 0, checkBitBytes.Length);
            byte checkRes = _stringChange.CalculateChecksum(checkBitBytes);

            if (checkRes != checksumByte)
            {
                _logger.Info($"指令校验失败:{_stringChange.bytesToHexStr(buffer,buffer.Length)}");
                return FilterResult.Cache;
            }
            
            request = new BufferRequestInfo()
            {
                header = headerByte,
                terminalType = terminalTypeByte,
                terminalAddr = terminalAddrStr,
                serialNumber = serialNumberByte,
                identCode = identCodeByte,
                objType = objTypeByte,
                contentLen = contentLen,
                content = contentStr,
                body = contentBytes,
                checkBit = checksumByte,
                tail = tailByte,
                buffer = new ByteBlock(buffer),
            };
            
            return FilterResult.Success;
        }
        catch (Exception e)
        {
            return FilterResult.Cache;
        }
    }
}