namespace ZB.MOM.WW.OtOpcUa.OpcUaServer;
///
/// Gitea #694 item 2: the opt-in ServerHistorian:EventReadHorizon — HistoryReadEvents never reads events older than
/// now − horizon. Off (, the default) a read is exact down to whatever its window says,
/// which on the Gateway means a reverse / end-only read walked back with forward reads proves "nothing older" with one
/// read down to the Unix epoch (#691) — ~3.8 s live on Runtime.dbo.Events, and an unfiltered one can hit the
/// gateway's 30 s SQL timeout. A forward read whose StartTime is far in the past costs the same on that table. The
/// horizon bounds both, at a stated price: events older than it are not returned, in either direction, on any backend.
///
internal static class EventHorizon
{
///
/// Raises the EARLIER bound of a fresh events window to the horizon's floor (now − horizon, inclusive): the
/// start of a forward [start, end) window, the exclusive lower end of a reverse (end, start] one.
///
/// The window start (the later bound of a reverse read).
/// The window end (the exclusive earlier bound of a reverse read).
/// Whether the read is newest-first (start > end).
/// The horizon; non-positive = none (nothing changes).
/// Now.
/// false when the whole window lies before the floor — the read is empty and must not be sent.
public static bool TryClamp(ref DateTime startUtc, ref DateTime endUtc, bool reverse, TimeSpan horizon, DateTime nowUtc)
{
if (horizon <= TimeSpan.Zero) return true;
var floor = nowUtc.Ticks - DateTime.MinValue.Ticks > horizon.Ticks
? new DateTime(nowUtc.Ticks - horizon.Ticks, DateTimeKind.Utc)
: new DateTime(0, DateTimeKind.Utc);
if (floor.Ticks == 0) return true;
if (reverse)
{
if (startUtc < floor) return false; // (end, start] lies wholly before the floor
var below = floor.AddTicks(-1); // exclusive lower end ⇒ the floor instant itself is read
if (endUtc < below) endUtc = below;
return true;
}
if (endUtc <= floor) return false; // [start, end) lies wholly before the floor
if (startUtc < floor) startUtc = floor;
return true;
}
}