using CoreAgent.Domain.Interfaces;
using CoreAgent.Domain.Interfaces.Network;
using CoreAgent.Domain.Models.Network;
using CoreAgent.Domain.Models.System;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using CoreAgent.Domain.Models.Protocol;
namespace CoreAgent.Infrastructure.Contexts;
///
/// 蜂窝网络领域上下文
///
public class CellularNetworkContext : ICellularNetworkContext, IDisposable
{
private readonly object _lock = new();
private CellularNetworkState _networkState;
private readonly NetworkCommandConfig _networkCommandConfig;
private readonly AppSettings _appSettings;
private string _neConfigKey = string.Empty;
private CancellationTokenSource _token;
private bool _isDisposed;
private bool _isInitialized;
private readonly INetworkIPEndPointManager _networkIPEndPointManager;
private NetworkConfigType _currentConfigType;
private readonly ILogger _logger;
private NetworkLayerLogs _networkLogs;
///
/// 获取取消令牌源
///
public CancellationTokenSource TokenSource => _token;
///
/// 是否已初始化
///
public bool IsInitialized => _isInitialized;
///
/// 网络IP端点管理器
///
public INetworkIPEndPointManager NetworkIPEndPointManager => _networkIPEndPointManager;
///
/// 当前网络配置类型
///
public NetworkConfigType CurrentConfigType => _currentConfigType;
///
/// 网络层日志配置
///
public NetworkLayerLogs NetworkLogs => _networkLogs;
public CellularNetworkContext(
IOptions networkCommandConfig,
IOptions appSettings,
INetworkIPEndPointManager networkIPEndPointManager,
ILogger logger)
{
_isDisposed = false;
_isInitialized = false;
_token = new CancellationTokenSource();
_networkCommandConfig = networkCommandConfig?.Value ?? throw new ArgumentNullException(nameof(networkCommandConfig));
_appSettings = appSettings?.Value ?? throw new ArgumentNullException(nameof(appSettings));
_networkIPEndPointManager = networkIPEndPointManager ?? throw new ArgumentNullException(nameof(networkIPEndPointManager));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_currentConfigType = NetworkConfigType.None;
_networkLogs = new NetworkLayerLogs();
}
///
/// 初始化上下文
///
/// 网络配置键
public void Initialize(string neConfigKey)
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (_isInitialized)
{
return;
}
if (string.IsNullOrEmpty(neConfigKey))
{
throw new ArgumentNullException(nameof(neConfigKey));
}
lock (_lock)
{
_networkIPEndPointManager.Clear();
_neConfigKey = neConfigKey;
_networkState = new CellularNetworkState(_neConfigKey);
_currentConfigType = NetworkConfigType.None;
_isInitialized = true;
}
}
///
/// 更新网络配置类型
///
/// 网络配置类型
public void UpdateNetworkConfigType(NetworkConfigType configType)
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
throw new InvalidOperationException("上下文未初始化");
}
lock (_lock)
{
_currentConfigType = configType;
}
}
///
/// 获取网络命令配置
///
/// 网络命令配置
public NetworkCommandConfig GetNetworkCommandConfig()
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
throw new InvalidOperationException("上下文未初始化");
}
lock (_lock)
{
return _networkCommandConfig ?? throw new InvalidOperationException("网络命令配置未设置");
}
}
///
/// 获取网络配置键
///
public string GetNeConfigKey()
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
throw new InvalidOperationException("上下文未初始化");
}
lock (_lock)
{
return _neConfigKey;
}
}
///
/// 获取指定类型的命令配置
///
/// 命令类型
/// 命令配置列表
public List GetCommandsByType(NetworkCommandType type)
{
lock (_lock)
{
return _networkCommandConfig?.GetCommandsByType(type) ?? new List();
}
}
///
/// 获取所有命令类型
///
/// 命令类型数组
public NetworkCommandType[] GetCommandTypes()
{
lock (_lock)
{
return _networkCommandConfig?.GetCommandTypes() ?? Array.Empty();
}
}
///
/// 获取网络状态
///
/// 网络状态
public CellularNetworkState GetNetworkState()
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
throw new InvalidOperationException("上下文未初始化");
}
lock (_lock)
{
return _networkState ?? throw new InvalidOperationException("网络状态未初始化");
}
}
///
/// 重置上下文状态
///
public void Reset()
{
if (_isDisposed)
{
_logger.LogWarning("尝试重置已释放的 CellularNetworkContext");
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
_logger.LogInformation("CellularNetworkContext 未初始化,跳过重置操作");
return;
}
lock (_lock)
{
try
{
if (_token != null && !_token.IsCancellationRequested)
{
_logger.LogDebug("正在取消当前的 CancellationTokenSource");
_token.Cancel();
}
}
catch (ObjectDisposedException ex)
{
_logger.LogWarning(ex, "CancellationTokenSource 已被释放");
}
catch (Exception ex)
{
_logger.LogError(ex, "取消操作时发生异常");
}
finally
{
try
{
_token?.Dispose();
_token = new CancellationTokenSource();
_neConfigKey = string.Empty;
_isInitialized = false;
_networkState = new CellularNetworkState(string.Empty);
_networkIPEndPointManager.Clear();
_currentConfigType = NetworkConfigType.None;
_networkLogs = new NetworkLayerLogs();
_logger.LogInformation("CellularNetworkContext 重置完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "重置 CellularNetworkContext 状态时发生异常");
throw;
}
}
}
}
///
/// 取消操作
///
public void Cancel()
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
lock (_lock)
{
_token.Cancel();
}
}
///
/// 获取应用设置
///
public AppSettings GetAppSettings()
{
if (_isDisposed)
{
throw new ObjectDisposedException(nameof(CellularNetworkContext));
}
if (!_isInitialized)
{
throw new InvalidOperationException("上下文未初始化");
}
return _appSettings;
}
///
/// 释放资源
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// 释放资源
///
/// 是否正在释放托管资源
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
{
return;
}
lock (_lock)
{
if (_isDisposed)
{
return;
}
if (disposing)
{
try
{
if (_token != null)
{
if (!_token.IsCancellationRequested)
{
_token.Cancel();
}
_token.Dispose();
}
}
catch (ObjectDisposedException)
{
// 忽略已释放的异常
}
catch (Exception)
{
// 记录其他异常
}
}
_isInitialized = false;
_isDisposed = true;
}
}
///
/// 析构函数
///
~CellularNetworkContext()
{
Dispose(false);
}
}