using Grpc.Core;
using GeViScopeBridge.Protos;
using GeViScopeBridge.SDK;
using GeViScopeBridge.Utils;
using Serilog;
namespace GeViScopeBridge.Services
{
///
/// gRPC service for monitor (video output) operations
///
public class MonitorServiceImplementation : MonitorService.MonitorServiceBase
{
private readonly StateQueryHandler _stateQuery;
private readonly ILogger _logger;
public MonitorServiceImplementation(StateQueryHandler stateQuery, ILogger logger)
{
_stateQuery = stateQuery ?? throw new ArgumentNullException(nameof(stateQuery));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
///
/// List all monitors/viewers (video outputs)
///
public override async Task ListMonitors(
ListMonitorsRequest request,
ServerCallContext context)
{
try
{
_logger.Information("ListMonitors called");
var monitors = await _stateQuery.EnumerateMonitorsAsync();
var response = new ListMonitorsResponse
{
TotalCount = monitors.Count
};
foreach (var monitor in monitors)
{
response.Monitors.Add(new MonitorInfo
{
Id = monitor.Id,
Name = monitor.Name,
Description = monitor.Description,
IsActive = monitor.IsActive,
CurrentCameraId = monitor.CurrentCameraId,
Status = monitor.Status,
LastUpdated = new Timestamp
{
Seconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
Nanos = 0
}
});
}
_logger.Information("ListMonitors completed: {Count} monitors", monitors.Count);
return response;
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to list monitors");
throw ErrorTranslator.CreateRpcException(ex, "Failed to list monitors");
}
}
///
/// Get detailed information about a specific monitor
///
public override async Task GetMonitor(
GetMonitorRequest request,
ServerCallContext context)
{
try
{
_logger.Information("GetMonitor called for monitor {MonitorId}", request.MonitorId);
// Enumerate all monitors and find the requested one
var monitors = await _stateQuery.EnumerateMonitorsAsync();
var monitor = monitors.FirstOrDefault(m => m.Id == request.MonitorId);
if (monitor == null)
{
throw new RpcException(new Status(StatusCode.NotFound,
$"Monitor with ID {request.MonitorId} not found"));
}
var response = new MonitorInfo
{
Id = monitor.Id,
Name = monitor.Name,
Description = monitor.Description,
IsActive = monitor.IsActive,
CurrentCameraId = monitor.CurrentCameraId,
Status = monitor.Status,
LastUpdated = new Timestamp
{
Seconds = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
Nanos = 0
}
};
_logger.Information("GetMonitor completed for monitor {MonitorId}", request.MonitorId);
return response;
}
catch (RpcException)
{
throw; // Re-throw RpcExceptions as-is
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to get monitor {MonitorId}", request.MonitorId);
throw ErrorTranslator.CreateRpcException(ex, "Failed to get monitor");
}
}
}
}