using ScadaLink.SiteRuntime;
using ScadaLink.SiteRuntime.Scripts;

namespace ScadaLink.SiteRuntime.Tests.Scripts;

/// <summary>
/// SiteRuntime-009: the dedicated script-execution scheduler must run script bodies on
/// its own dedicated threads, not on the shared .NET thread pool, so blocking script
/// I/O cannot starve the global pool.
/// </summary>
public class ScriptExecutionSchedulerTests
{
    [Fact]
    public async Task Scheduler_RunsWork_OffTheThreadPool()
    {
        using var scheduler = new ScriptExecutionScheduler(2);

        bool wasThreadPoolThread = true;
        string? threadName = null;

        await Task.Factory.StartNew(() =>
        {
            wasThreadPoolThread = Thread.CurrentThread.IsThreadPoolThread;
            threadName = Thread.CurrentThread.Name;
        }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, scheduler);

        Assert.False(wasThreadPoolThread,
            "Script work must not run on a shared thread-pool thread.");
        Assert.StartsWith("script-execution-", threadName);
    }

    [Fact]
    public void Scheduler_RespectsConfiguredThreadCount()
    {
        using var scheduler = new ScriptExecutionScheduler(4);
        Assert.Equal(4, scheduler.MaximumConcurrencyLevel);
    }

    [Fact]
    public void Scheduler_Shared_ReturnsSameInstanceForOptions()
    {
        var options = new SiteRuntimeOptions { ScriptExecutionThreadCount = 3 };
        var a = ScriptExecutionScheduler.Shared(options);
        var b = ScriptExecutionScheduler.Shared(options);
        Assert.Same(a, b);
    }
}
