namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
///
/// Scope-aware view onto the instance's attributes, anchored at a path prefix.
/// Attributes["X"] on the root scope resolves to canonical name "X";
/// on a composition with prefix "TempSensor" it resolves to "TempSensor.X".
///
///
/// Thread-model note (SiteRuntime-012): the indexer get/set block synchronously
/// on the Instance Actor Ask (and, for data-connected attributes, the DCL
/// round-trip). This is safe because script bodies execute on the dedicated
/// threads (SiteRuntime-009), not the
/// shared — so a blocked accessor
/// cannot starve unrelated Akka dispatchers or HTTP request handling. The async
/// variants (/) are still preferred
/// where the script can await, as they avoid holding a dedicated thread idle for
/// the duration of each round-trip.
///
///
public class AttributeAccessor
{
private readonly ScriptRuntimeContext _ctx;
/// Canonical-name prefix, e.g. "" for root or "TempSensor" for a composition.
public string ScopePrefix { get; }
///
/// Initializes a new instance of the AttributeAccessor with the specified context and prefix.
///
/// The script runtime context.
/// The canonical-name prefix for attribute resolution.
public AttributeAccessor(ScriptRuntimeContext ctx, string prefix)
{
_ctx = ctx;
ScopePrefix = prefix;
}
///
/// Resolves a key to its full canonical name by applying the scope prefix.
///
/// The attribute key to resolve.
/// The fully qualified canonical name (e.g. "TempSensor.X" or "X" for the root scope).
public string Resolve(string key) =>
ScopePrefix.Length == 0 ? key : ScopePrefix + "." + key;
///
/// Gets or sets an attribute value synchronously by canonical name.
///
/// The attribute key.
public object? this[string key]
{
// Both reads and writes block on the actor Ask; the write also blocks
// on the DCL round-trip for data-connected attributes. The async
// variants (GetAsync/SetAsync) are preferred where awaiting is possible.
get => _ctx.GetAttribute(Resolve(key)).GetAwaiter().GetResult();
set => _ctx.SetAttribute(Resolve(key), value?.ToString() ?? string.Empty).GetAwaiter().GetResult();
}
///
/// Gets an attribute value asynchronously.
///
/// The attribute key.
/// A task that resolves to the attribute value, or null if not set.
public Task