using Org.Eclipse.Tahu.Protobuf;

namespace ZB.MOM.WW.OtOpcUa.Driver.Mqtt.SparkplugSimulator;

/// <summary>
///     One metric in a simulated edge node's (or device's) catalog: the name a birth certificate
///     declares, the alias it binds that name to for the life of the birth, the Sparkplug datatype, and
///     the value the birth publishes.
/// </summary>
/// <param name="Name">The stable metric name — what an authored tag binds to.</param>
/// <param name="Alias">
///     The per-birth alias. <b>Mutable across rebirths by design</b>: reassigning an alias to a
///     different metric on a rebirth is legal Sparkplug and is §3.6 matrix case (i), the one that
///     silently mis-routes data in a driver that binds by alias.
/// </param>
/// <param name="DataType">The Sparkplug datatype the birth declares for this metric.</param>
/// <param name="Value">
///     The value the birth publishes. <see langword="null"/> is encoded as an explicit
///     <c>is_null</c> metric rather than as an omitted value — those mean different things on the wire.
/// </param>
public sealed record SparkplugMetricSeed(string Name, ulong Alias, DataType DataType, object? Value)
{
    /// <summary>Returns this seed with a different value, leaving name/alias/type alone.</summary>
    /// <param name="value">The new value.</param>
    /// <returns>The updated seed.</returns>
    public SparkplugMetricSeed WithValue(object? value) => this with { Value = value };

    /// <summary>Returns this seed with a different alias — the alias-reuse case.</summary>
    /// <param name="alias">The new alias.</param>
    /// <returns>The updated seed.</returns>
    public SparkplugMetricSeed WithAlias(ulong alias) => this with { Alias = alias };
}
