using MBN_STOCK_WEBVIEW.Core.Playout; using MBN_STOCK_WEBVIEW.Infrastructure; using MBN_STOCK_WEBVIEW.Infrastructure.Diagnostics; using MMoneyCoderSharp.Data; namespace MBN_STOCK_WEBVIEW; public sealed partial class MainWindow { private readonly INativeOperatorLogWriter _nativeOperatorLogWriter = new NativeOperatorLogWriter(); private readonly NativeOperatorLogTransitionTracker _nativeOperatorTransitionTracker = new(); private readonly NativeOperatorCommandLogTracker _nativeOperatorCommandTracker = new(); private int _nativeStartupRecorded; private int _nativeShutdownRecorded; private void LogNativeOperatorStartup() { if (Interlocked.Exchange(ref _nativeStartupRecorded, 1) == 0) { TryWriteNativeOperatorRecord(NativeOperatorLogRecord.ForStartup()); } } private void LogNativeOperatorShutdown() { if (Interlocked.Exchange(ref _nativeShutdownRecorded, 1) == 0) { TryWriteNativeOperatorRecord(NativeOperatorLogRecord.ForShutdown()); } } private void ObserveNativeDatabaseState( DataSourceKind source, DatabaseHealthState state) { if (_nativeOperatorTransitionTracker.TryObserveDatabaseState( source, state, out var record)) { TryWriteNativeOperatorRecord(record); } } private void ObserveNativeTornadoState(PlayoutConnectionState state) { if (_nativeOperatorTransitionTracker.TryObserveTornadoState(state, out var record)) { TryWriteNativeOperatorRecord(record); } } private void LogNativePlayoutCommandRequested(string command) { if (TryMapNativePlayoutCommand(command, out var mapped) && _nativeOperatorCommandTracker.TryBegin(mapped, out var record)) { TryWriteNativeOperatorRecord(record); } } private void LogNativePlayoutCommandCompleted( string command, PlayoutResultCode result) { if (!TryMapNativePlayoutCommand(command, out var mapped)) { return; } if (result is PlayoutResultCode.OutcomeUnknown or PlayoutResultCode.TimedOut || !TryMapNativePlayoutCompletion(result, out var completion)) { if (_nativeOperatorCommandTracker.TryMarkOutcomeUnknown(mapped, out var unknownRecord)) { TryWriteNativeOperatorRecord(unknownRecord); } return; } if (_nativeOperatorCommandTracker.TryComplete(mapped, completion, out var record)) { TryWriteNativeOperatorRecord(record); } } private void LogNativePlayoutCommandCompleted( string command, NativeOperatorPlayoutCompletion completion) { if (TryMapNativePlayoutCommand(command, out var mapped) && _nativeOperatorCommandTracker.TryComplete(mapped, completion, out var record)) { TryWriteNativeOperatorRecord(record); } } private void LogNativePlayoutOutcomeUnknown(string command) { if (TryMapNativePlayoutCommand(command, out var mapped) && _nativeOperatorCommandTracker.TryMarkOutcomeUnknown(mapped, out var record)) { TryWriteNativeOperatorRecord(record); } } private void LogCurrentNativePlayoutOutcomeUnknown() { if (_nativeOperatorCommandTracker.TryMarkCurrentOutcomeUnknown(out var record)) { TryWriteNativeOperatorRecord(record); } } private void TryWriteNativeOperatorRecord(NativeOperatorLogRecord record) { try { _ = _nativeOperatorLogWriter.TryWrite(record); } catch { // Logging is strictly best effort and cannot affect operator commands. } } private static bool TryMapNativePlayoutCommand( string command, out NativeOperatorPlayoutCommand mapped) { mapped = command switch { "prepare" => NativeOperatorPlayoutCommand.Prepare, "take-in" => NativeOperatorPlayoutCommand.TakeIn, "next" => NativeOperatorPlayoutCommand.Next, "take-out" => NativeOperatorPlayoutCommand.TakeOut, _ => default }; return mapped != default; } private static bool TryMapNativePlayoutCompletion( PlayoutResultCode result, out NativeOperatorPlayoutCompletion mapped) { mapped = result switch { PlayoutResultCode.Success => NativeOperatorPlayoutCompletion.Succeeded, PlayoutResultCode.Rejected => NativeOperatorPlayoutCompletion.Rejected, PlayoutResultCode.Cancelled => NativeOperatorPlayoutCompletion.Cancelled, PlayoutResultCode.Unavailable => NativeOperatorPlayoutCompletion.Unavailable, PlayoutResultCode.Failed => NativeOperatorPlayoutCompletion.Failed, _ => default }; return mapped != default; } }