using LTEMvcApp.Models;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
namespace LTEMvcApp.Services;
///
/// LTE日志解析服务 - 实现JavaScript _logListParse方法的核心功能
///
public class LogParserService
{
#region 常量定义
///
/// HFN回绕阈值
///
private const int HFN_WRAP_THRESHOLD = 512;
///
/// 最大日志数量
///
private const int LOGS_MAX = 2000000;
#endregion
#region 正则表达式
///
/// PHY层日志正则表达式
///
private static readonly Regex RegExpPhy = new(@"^([a-f0-9\-]+)\s+([a-f0-9\-]+)\s+([\d\.\-]+) (\w+): (.+)", RegexOptions.Compiled);
///
/// 信息1正则表达式
///
private static readonly Regex RegExpInfo1 = new(@"^([\w\-]+): (.+)", RegexOptions.Compiled);
///
/// 信息2正则表达式
///
private static readonly Regex RegExpInfo2 = new(@"^([\w]+) (.+)", RegexOptions.Compiled);
///
/// IP日志正则表达式
///
private static readonly Regex RegExpIP = new(@"^(len=\d+)\s+(\S+)\s+(.*)", RegexOptions.Compiled);
///
/// IPsec日志正则表达式
///
private static readonly Regex RegExpIPsec = new(@"^len=(\d+)\s+(.*)", RegexOptions.Compiled);
///
/// SDU长度正则表达式
///
private static readonly Regex RegExpSDULen = new(@"SDU_len=(\d+)", RegexOptions.Compiled);
///
/// SIP日志正则表达式
///
private static readonly Regex RegExpSIP = new(@"^([:\.\[\]\da-f]+)\s+(\S+) (.+)", RegexOptions.Compiled);
///
/// 媒体请求正则表达式
///
private static readonly Regex RegExpMediaReq = new(@"^(\S+) (.+)", RegexOptions.Compiled);
///
/// 信号记录正则表达式
///
private static readonly Regex RegExpSignalRecord = new(@"Link:\s([\w\d]+)@(\d+)", RegexOptions.Compiled);
///
/// 小区ID正则表达式
///
private static readonly Regex RegExpCellID = new(@"^([a-f0-9\-]+) (.+)", RegexOptions.Compiled);
///
/// RRC UE ID正则表达式
///
private static readonly Regex RegExpRRC_UE_ID = new(@"Changing UE_ID to 0x(\d+)", RegexOptions.Compiled);
///
/// RRC TMSI正则表达式
///
private static readonly Regex RegExpRRC_TMSI = new(@"(5G|m)-TMSI '([\dA-F]+)'H", RegexOptions.Compiled);
///
/// RRC新ID正则表达式
///
private static readonly Regex RegExpRRC_NEW_ID = new(@"newUE-Identity (['\dA-FH]+)", RegexOptions.Compiled);
///
/// RRC CRNTI正则表达式
///
private static readonly Regex RegExpRRC_CRNTI = new(@"c-RNTI '([\dA-F]+)'H", RegexOptions.Compiled);
///
/// NAS TMSI正则表达式
///
private static readonly Regex RegExpNAS_TMSI = new(@"m-TMSI = 0x([\da-f]+)", RegexOptions.Compiled);
///
/// NAS 5G TMSI正则表达式
///
private static readonly Regex RegExpNAS_5GTMSI = new(@"5G-TMSI = 0x([\da-f]+)", RegexOptions.Compiled);
///
/// RRC频段组合正则表达式
///
private static readonly Regex RegExpRRC_BC = new(@"(EUTRA|MRDC|NR|NRDC) band combinations", RegexOptions.Compiled);
///
/// PDCCH正则表达式
///
private static readonly Regex RegExpPDCCH = new(@"^\s*(.+)=(\d+)$", RegexOptions.Compiled);
///
/// S1/NGAP正则表达式
///
private static readonly Regex RegExpS1NGAP = new(@"^([\da-f\-]+)\s+([\da-f\-]+) (([^\s]+) .+)", RegexOptions.Compiled);
///
/// 十六进制转储正则表达式
///
private static readonly Regex RegExpHexDump = new(@"^[\da-f]+:(\s+[\da-f]{2}){1,16}\s+.{1,16}$", RegexOptions.Compiled);
#endregion
#region 私有字段
///
/// 字符串到ID的映射缓存
///
private readonly Dictionary _stringToIdCache = new();
///
/// ID到字符串的映射缓存
///
private readonly Dictionary _idToStringCache = new();
///
/// 字符串ID计数器
///
private int _stringIdCounter = 0;
#endregion
#region 公共方法
///
/// 解析日志列表 - 对应JavaScript的_logListParse方法
///
/// LTE客户端
/// 日志列表
/// 是否为WebSocket消息
public void ParseLogList(LTEClient client, List logs, bool isWebSocket = false)
{
var length = logs.Count;
for (int i = 0; i < length; i++)
{
var log = logs[i];
log.Message = log.Message + "";
client.AddLog(log);
// 解析消息
switch (log.Layer)
{
case "PHY":
if (!ParsePhyLog(client, log, log.Message, isWebSocket)) continue;
ProcessPhyLog(client, log);
break;
case "RRC":
ParseCellId(client, log, isWebSocket);
var rrcUeIdMatch = RegExpRRC_UE_ID.Match(log.Message);
if (rrcUeIdMatch.Success)
{
SetSameUe(client, log, int.Parse(rrcUeIdMatch.Groups[1].Value, System.Globalization.NumberStyles.HexNumber));
continue;
}
var infoMatch = RegExpInfo1.Match(log.Message);
if (infoMatch.Success)
{
if (!SetLogInfo(client, log, infoMatch.Groups[1].Value)) continue;
log.Message = infoMatch.Groups[2].Value;
ProcessRrcLog(client, log);
}
var bcMatch = RegExpRRC_BC.Match(log.Message);
if (bcMatch.Success)
{
try
{
var data = log.GetDataString();
var jsonData = JsonConvert.DeserializeObject