namespace ScadaLink.CentralUI.ScriptAnalysis;

/// <summary>
/// Globals type seen by user scripts during analysis. Mirrors the surface
/// the runtime exposes (see ScadaLink.SiteRuntime.Scripts.ScriptGlobals).
/// The methods and indexers here are never invoked — Roslyn only reads
/// their signatures to know what's in scope while compiling for diagnostics
/// and completions.
/// </summary>
public class ScriptHost
{
    public IReadOnlyDictionary<string, object?> Parameters { get; init; } =
        new Dictionary<string, object?>();

    /// <summary>Invokes another shared script by name and returns its result.</summary>
    public object? CallShared(string name, params object?[] args) => null;

    /// <summary>Invokes another script on the same template and returns its result.</summary>
    public object? CallScript(string name, params object?[] args) => null;

    // Scope-aware accessors. SCADA-specific completion + diagnostics live in
    // ScriptAnalysisService; these stubs exist so the bare Roslyn pass doesn't
    // produce CS0103 errors on Attributes / Children / Parent.

    public AttributeBag Attributes { get; } = new();
    public ChildrenBag Children { get; } = new();
    public CompositionBag? Parent { get; } = new();

    public class AttributeBag
    {
        public object? this[string name]
        {
            get => null;
            set { /* no-op for analyzer */ }
        }
        public System.Threading.Tasks.Task<object?> GetAsync(string name) =>
            System.Threading.Tasks.Task.FromResult<object?>(null);
        public System.Threading.Tasks.Task SetAsync(string name, object? value) =>
            System.Threading.Tasks.Task.CompletedTask;
    }

    public class CompositionBag
    {
        public AttributeBag Attributes { get; } = new();
        public System.Threading.Tasks.Task<object?> CallScript(string name, params object?[] args) =>
            System.Threading.Tasks.Task.FromResult<object?>(null);
    }

    public class ChildrenBag
    {
        public CompositionBag this[string compositionName] => new();
    }
}
