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"); } } } }