using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browse;

/// <summary>
///     Populates the five sub-attribute references on <see cref="AlarmConditionInfo"/>
///     by Galaxy convention. The server-level <c>AlarmConditionService</c> (PR 2.2) uses
///     these to subscribe to live alarm-state attributes and to route ack writes back to
///     the alarm tag.
/// </summary>
/// <remarks>
///     Galaxy alarms expose four runtime attributes plus a write-only ack target,
///     consistently named on every alarm-bearing object:
///     <list type="bullet">
///       <item><c>&lt;tag&gt;.&lt;attr&gt;.InAlarm</c></item>
///       <item><c>&lt;tag&gt;.&lt;attr&gt;.Priority</c></item>
///       <item><c>&lt;tag&gt;.&lt;attr&gt;.DescAttrName</c></item>
///       <item><c>&lt;tag&gt;.&lt;attr&gt;.Acked</c></item>
///       <item><c>&lt;tag&gt;.&lt;attr&gt;.AckMsg</c></item>
///     </list>
///     This is the same convention the legacy <c>GalaxyAlarmTracker</c> hard-coded; we
///     concentrate it here so PR 2.2's service receives complete <c>AlarmConditionInfo</c>
///     rows during discovery without the server needing to know the convention.
/// </remarks>
internal static class AlarmRefBuilder
{
    private const string InAlarmSuffix = ".InAlarm";
    private const string PrioritySuffix = ".Priority";
    private const string DescAttrNameSuffix = ".DescAttrName";
    private const string AckedSuffix = ".Acked";
    private const string AckMsgSuffix = ".AckMsg";

    /// <summary>
    ///     Build an <see cref="AlarmConditionInfo"/> for an alarm-bearing attribute with all
    ///     five sub-attribute references populated. <paramref name="fullReference"/> is the
    ///     attribute's full reference (e.g. <c>"Tank1.Level.HiHi"</c>); the convention prefixes
    ///     each suffix to it.
    /// </summary>
    /// <param name="fullReference">The full reference of the alarm-bearing attribute.</param>
    /// <param name="initialSeverity">The initial alarm severity level.</param>
    /// <param name="initialDescription">The initial alarm description.</param>
    public static AlarmConditionInfo Build(
        string fullReference,
        AlarmSeverity initialSeverity = AlarmSeverity.Medium,
        string? initialDescription = null) => new(
            SourceName: fullReference,
            InitialSeverity: initialSeverity,
            InitialDescription: initialDescription,
            InAlarmRef: fullReference + InAlarmSuffix,
            PriorityRef: fullReference + PrioritySuffix,
            DescAttrNameRef: fullReference + DescAttrNameSuffix,
            AckedRef: fullReference + AckedSuffix,
            AckMsgWriteRef: fullReference + AckMsgSuffix);
}
