using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace LeanContext;

/// <summary>
///     LEAN globals type for the memory probe. Its transitive reference closure is only
///     {LeanContext, Core.Abstractions} — deliberately NO Roslyn — so the per-script cost
///     of the Roslyn reference-manager loading the globalsType's closure (dotnet/roslyn#22219)
///     can be measured against the heavy <c>VirtualTagContext</c>, whose closure pulls in
///     Microsoft.CodeAnalysis.CSharp.Scripting.
///     <para>
///         <see cref="GetTag"/> returns the same <see cref="DataValueSnapshot"/> type that
///         <c>VirtualTagContext.GetTag</c> returns, so the probe's script source
///         (<c>ctx.GetTag("x").Value</c>) is byte-identical for both modes — the ONLY
///         difference is which assembly closure the globalsType lives in.
///     </para>
/// </summary>
public sealed class LeanCtx
{
    private readonly System.Collections.Generic.Dictionary<string, DataValueSnapshot> _d = new();

    public DataValueSnapshot GetTag(string p) =>
        _d.TryGetValue(p, out var v) ? v : new DataValueSnapshot(null, 0u, null, default);
}

/// <summary>
///     LEAN analogue of the prod <c>ScriptGlobals&lt;TContext&gt;</c> wrapper: exposes a
///     named <c>ctx</c> property so the script source can be byte-identical to the heavy
///     path (<c>ctx.GetTag(...).Value</c>). Lives in the LeanContext assembly, so its
///     reference closure is {LeanContext, Core.Abstractions} — NO Roslyn. This is the A0
///     "globals type in a lean assembly" treatment.
/// </summary>
public sealed class LeanGlobals
{
    public LeanCtx ctx { get; set; } = new();
}
