using ScadaLink.Commons.Types.Scripts;
using ScadaLink.SiteRuntime.Scripts;

namespace ScadaLink.SiteRuntime.Tests.Scripts;

/// <summary>
/// Phase 1 of the script-scope rollout: verify path arithmetic for the new
/// Attributes / Children / Parent accessors. The actor-mediated reads/writes
/// are exercised end-to-end in Phase 2 once flattening carries scope info.
/// </summary>
public class ScopeAccessorTests
{
    [Fact]
    public void Root_SelfPath_Empty()
    {
        Assert.Equal("", ScriptScope.Root.SelfPath);
        Assert.Null(ScriptScope.Root.ParentPath);
        Assert.False(ScriptScope.Root.HasParent);
    }

    [Fact]
    public void CompositionScope_HasParent()
    {
        var scope = new ScriptScope("TempSensor", "");
        Assert.True(scope.HasParent);
        Assert.Equal("", scope.ParentPath);
    }

    [Fact]
    public void AttributeAccessor_RootScope_ResolvesBareKey()
    {
        var acc = new AttributeAccessor(null!, "");
        Assert.Equal("Temperature", acc.Resolve("Temperature"));
    }

    [Fact]
    public void AttributeAccessor_ComposedScope_PrependsPath()
    {
        var acc = new AttributeAccessor(null!, "TempSensor");
        Assert.Equal("TempSensor.Temperature", acc.Resolve("Temperature"));
    }

    [Fact]
    public void AttributeAccessor_NestedScope_ChainsPath()
    {
        var acc = new AttributeAccessor(null!, "Motor.TempSensor");
        Assert.Equal("Motor.TempSensor.Temperature", acc.Resolve("Temperature"));
    }

    [Fact]
    public void CompositionAccessor_AttributesShareScope()
    {
        var comp = new CompositionAccessor(null!, "TempSensor");
        Assert.Equal("TempSensor", comp.Path);
        Assert.Equal("TempSensor", comp.Attributes.ScopePrefix);
    }

    [Fact]
    public void CompositionAccessor_ResolveScript_PrependsPath()
    {
        var comp = new CompositionAccessor(null!, "TempSensor");
        Assert.Equal("TempSensor.Sample", comp.ResolveScript("Sample"));
    }

    [Fact]
    public void CompositionAccessor_EmptyPath_LeavesScriptNameBare()
    {
        var comp = new CompositionAccessor(null!, "");
        Assert.Equal("Sample", comp.ResolveScript("Sample"));
    }

    [Fact]
    public void ChildrenAccessor_FromRoot_GivesUnpathedChild()
    {
        var children = new ChildrenAccessor(null!, "");
        var temp = children["TempSensor"];
        Assert.Equal("TempSensor", temp.Path);
    }

    [Fact]
    public void ChildrenAccessor_FromComposition_PrefixesChild()
    {
        var children = new ChildrenAccessor(null!, "Motor");
        var temp = children["TempSensor"];
        Assert.Equal("Motor.TempSensor", temp.Path);
    }
}
