using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian;   // AlarmHistorianEvent
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;      // AlarmSeverity
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Mapping;

namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests.Mapping;

public sealed class AlarmEventMapperTests
{
    [Fact]
    public void Maps_source_time_type_and_rich_properties()
    {
        var a = new AlarmHistorianEvent("A1", "Area/Line/Pump1", "HiHi", "LimitAlarm",
            AlarmSeverity.High, "Activated", "Temp high", "operator1", "ack note",
            new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc));
        var e = AlarmEventMapper.ToHistorianEvent(a);
        Assert.Equal("Area/Line/Pump1", e.SourceName);
        Assert.Equal("LimitAlarm", e.Type);
        Assert.Equal(new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc), e.EventTime.ToDateTime());
        // The wire Id is deliberately left unset — the gateway's SendEvent rejects a client-supplied
        // event id. The alarm's own id is carried as a property instead.
        Assert.Equal(string.Empty, e.Id);
        Assert.Equal("A1", e.Properties["AlarmId"]);
        Assert.Equal("HiHi", e.Properties["AlarmName"]);
        Assert.Equal("Activated", e.Properties["EventKind"]);
        Assert.Equal("High", e.Properties["Severity"]);
        Assert.Equal("operator1", e.Properties["User"]);
        Assert.Equal("ack note", e.Properties["Comment"]);
        Assert.Equal("Temp high", e.Properties["Message"]);
    }

    [Fact]
    public void Null_comment_is_omitted_not_null()
    {
        var a = new AlarmHistorianEvent("A", "S", "N", "DiscreteAlarm", AlarmSeverity.Low, "Cleared", "m", "system", null,
            new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc));
        Assert.False(AlarmEventMapper.ToHistorianEvent(a).Properties.ContainsKey("Comment"));
    }

    [Fact]
    public void Wire_id_is_never_set_and_blank_alarm_id_adds_no_property()
    {
        // A blank AlarmId must NOT fall back to a generated wire Id (the gateway rejects any id) and
        // must not add an empty AlarmId property.
        var a = new AlarmHistorianEvent("", "S", "N", "DiscreteAlarm", AlarmSeverity.Low, "Cleared", "m", "system", null,
            new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc));
        var e = AlarmEventMapper.ToHistorianEvent(a);
        Assert.Equal(string.Empty, e.Id);
        Assert.False(e.Properties.ContainsKey("AlarmId"));
    }
}
