namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
///
/// Flow Debugger step logs (design 2026-09-09 D6): the ambient "which step is running right now"
/// marker used to attribute runtime-sourced log lines to a step node.
///
/// A ScriptLog row names its owning step explicitly (D2), but the runtime lines the
/// node logs on the script's behalf are produced deep inside a helper — the helper knows its
/// pre-minted step EventId, the logging call site does not. Rather than thread that id
/// through every internal call, the helpers open a scope around their body and
/// reads when no explicit id is supplied.
///
/// so the value flows through the helper's own awaits and
/// nowhere else: it is captured by continuations started inside the scope and is invisible to
/// concurrent runs on other threads of the script execution pool. Lines logged outside any scope
/// see and fall back to the execution's anchor row (D2).
///
public static class TraceStepScope
{
private static readonly AsyncLocal _current = new();
/// The step EventId owning the currently executing helper body, or outside any scope.
public static Guid? Current => _current.Value;
///
/// Sets the current step for the scope's lifetime; restores the previous value on dispose,
/// so nested scopes (a helper calling another helper) unwind correctly.
///
/// The pre-minted EventId of the step row this body belongs to.
/// A handle that restores the previous ambient value when disposed.
public static IDisposable Enter(Guid stepEventId)
{
var prev = _current.Value;
_current.Value = stepEventId;
return new Restore(prev);
}
/// Restores the ambient step id captured at time.
private sealed class Restore(Guid? prev) : IDisposable
{
///
public void Dispose() => _current.Value = prev;
}
}