using System.Text.Json;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;

namespace ZB.MOM.WW.ScadaBridge.TemplateEngine.Tests.Flattening;

public class DeploymentPackageTests
{
    [Fact]
    public void DeploymentPackage_JsonSerializable()
    {
        var package = new DeploymentPackage
        {
            InstanceUniqueName = "PumpStation1",
            DeploymentId = "dep-abc123",
            RevisionHash = "sha256:abcdef1234567890",
            DeployedBy = "admin@company.com",
            DeployedAtUtc = new DateTimeOffset(2026, 3, 16, 12, 0, 0, TimeSpan.Zero),
            Configuration = new FlattenedConfiguration
            {
                InstanceUniqueName = "PumpStation1",
                TemplateId = 1,
                SiteId = 1,
                Attributes =
                [
                    new ResolvedAttribute
                    {
                        CanonicalName = "Temperature",
                        Value = "25.0",
                        DataType = "Double",
                        BoundDataConnectionId = 100,
                        BoundDataConnectionName = "OPC-Server1",
                        BoundDataConnectionProtocol = "OpcUa",
                        DataSourceReference = "ns=2;s=Temp"
                    }
                ],
                Alarms =
                [
                    new ResolvedAlarm
                    {
                        CanonicalName = "HighTemp",
                        TriggerType = "RangeViolation",
                        PriorityLevel = 1
                    }
                ],
                Scripts =
                [
                    new ResolvedScript
                    {
                        CanonicalName = "Monitor",
                        Code = "var x = Attributes[\"Temperature\"].Value;"
                    }
                ]
            },
            PreviousRevisionHash = null
        };

        var json = JsonSerializer.Serialize(package);
        Assert.NotNull(json);
        Assert.Contains("PumpStation1", json);
        Assert.Contains("sha256:abcdef1234567890", json);

        var deserialized = JsonSerializer.Deserialize<DeploymentPackage>(json);
        Assert.NotNull(deserialized);
        Assert.Equal("PumpStation1", deserialized.InstanceUniqueName);
        Assert.Equal("dep-abc123", deserialized.DeploymentId);
        Assert.Single(deserialized.Configuration.Attributes);
        Assert.Equal("Temperature", deserialized.Configuration.Attributes[0].CanonicalName);
    }

    [Fact]
    public void DeploymentPackage_WithDiff_Serializable()
    {
        var package = new DeploymentPackage
        {
            InstanceUniqueName = "Inst1",
            DeploymentId = "dep-1",
            RevisionHash = "sha256:new",
            DeployedBy = "admin",
            DeployedAtUtc = DateTimeOffset.UtcNow,
            Configuration = new FlattenedConfiguration { InstanceUniqueName = "Inst1" },
            Diff = new ConfigurationDiff
            {
                InstanceUniqueName = "Inst1",
                OldRevisionHash = "sha256:old",
                NewRevisionHash = "sha256:new",
                AttributeChanges =
                [
                    new DiffEntry<ResolvedAttribute>
                    {
                        CanonicalName = "Temp",
                        ChangeType = DiffChangeType.Changed,
                        OldValue = new ResolvedAttribute { CanonicalName = "Temp", Value = "25", DataType = "Double" },
                        NewValue = new ResolvedAttribute { CanonicalName = "Temp", Value = "50", DataType = "Double" }
                    }
                ]
            },
            PreviousRevisionHash = "sha256:old"
        };

        var json = JsonSerializer.Serialize(package);
        var deserialized = JsonSerializer.Deserialize<DeploymentPackage>(json);

        Assert.NotNull(deserialized?.Diff);
        Assert.True(deserialized.Diff.HasChanges);
        Assert.Equal("sha256:old", deserialized.PreviousRevisionHash);
    }

    [Fact]
    public void FlattenedConfiguration_DefaultValues()
    {
        var config = new FlattenedConfiguration();

        Assert.Equal(string.Empty, config.InstanceUniqueName);
        Assert.Empty(config.Attributes);
        Assert.Empty(config.Alarms);
        Assert.Empty(config.Scripts);
    }
}
