using LehrerApp.Sync.Models;
namespace LehrerApp.Sync;
///
/// Entscheidet bei kollidierenden Events welcher gewinnt.
/// Desktop hat Vorrang vor Companion. Bei Gleichstand gewinnt der spätere Timestamp.
///
public class ConflictResolver
{
private readonly EventQueue _queue;
public ConflictResolver(EventQueue queue)
{
_queue = queue;
}
///
/// Prüft ob ein Remote-Event mit einem lokalen Event kollidiert.
/// Gibt null zurück wenn kein Konflikt besteht.
///
public ConflictEntry? TryResolve(SyncEvent remoteEvent, string localDeviceId)
{
// Lokalen Event für dieselbe Entity suchen
var localEvent = _queue.GetPending()
.FirstOrDefault(e =>
e.EntityType == remoteEvent.EntityType &&
e.EntityId == remoteEvent.EntityId &&
e.DeviceId != remoteEvent.DeviceId);
if (localEvent is null)
return null; // kein Konflikt – Remote-Event einfach anwenden
// Konflikt aufgelöst – Gewinner bestimmen
var winner = DetermineWinner(localEvent, remoteEvent);
var resolution = winner == localEvent ? "LocalWon" : "RemoteWon";
// Wenn Remote gewinnt: lokalen Event aus Queue entfernen
if (winner == remoteEvent)
_queue.Acknowledge([localEvent.EventId]);
return new ConflictEntry
{
LocalEvent = localEvent,
RemoteEvent = remoteEvent,
Resolution = resolution,
};
}
private static SyncEvent DetermineWinner(SyncEvent local, SyncEvent remote)
{
// Regel 1: Desktop schlägt Companion
if (local.DeviceType == DeviceType.Desktop &&
remote.DeviceType == DeviceType.Companion)
return local;
if (remote.DeviceType == DeviceType.Desktop &&
local.DeviceType == DeviceType.Companion)
return remote;
// Regel 2: Späterer Timestamp gewinnt
return local.Timestamp >= remote.Timestamp ? local : remote;
}
}