using ZB.MOM.WW.GalaxyRepository.Grpc;

namespace ZB.MOM.WW.GalaxyRepository;

/// <summary>
///     Immutable snapshot of the Galaxy Repository browse data held by
///     <see cref="GalaxyHierarchyCache"/>. Multiple gRPC clients share the same
///     materialized object list and precomputed hierarchy index.
/// </summary>
/// <param name="Status">The cache freshness state at the time the entry was produced.</param>
/// <param name="Sequence">Monotonically increasing per process start; bumped on each heavy refresh.</param>
/// <param name="LastQueriedAt">UTC wall-clock of the most recent refresh attempt.</param>
/// <param name="LastSuccessAt">UTC wall-clock of the most recent successful refresh.</param>
/// <param name="LastDeployTime">The <c>galaxy.time_of_last_deploy</c> the data was pulled at.</param>
/// <param name="LastError">The most recent refresh error message, or <see langword="null"/>.</param>
/// <param name="Objects">The materialized Galaxy object list.</param>
/// <param name="Index">Precomputed lookup structures over <paramref name="Objects"/>.</param>
/// <param name="ObjectCount">Number of objects in the hierarchy.</param>
/// <param name="AreaCount">Number of area objects in the hierarchy.</param>
/// <param name="AttributeCount">Number of attributes across all objects.</param>
/// <param name="HistorizedAttributeCount">Number of historized attributes.</param>
/// <param name="AlarmAttributeCount">Number of alarm-bearing attributes.</param>
public sealed record GalaxyHierarchyCacheEntry(
    GalaxyCacheStatus Status,
    long Sequence,
    DateTimeOffset? LastQueriedAt,
    DateTimeOffset? LastSuccessAt,
    DateTimeOffset? LastDeployTime,
    string? LastError,
    IReadOnlyList<GalaxyObject> Objects,
    GalaxyHierarchyIndex Index,
    int ObjectCount,
    int AreaCount,
    int AttributeCount,
    int HistorizedAttributeCount,
    int AlarmAttributeCount)
{
    /// <summary>Gets an empty Galaxy hierarchy cache entry.</summary>
    public static GalaxyHierarchyCacheEntry Empty { get; } = new(
        Status: GalaxyCacheStatus.Unknown,
        Sequence: 0,
        LastQueriedAt: null,
        LastSuccessAt: null,
        LastDeployTime: null,
        LastError: null,
        Objects: Array.Empty<GalaxyObject>(),
        Index: GalaxyHierarchyIndex.Empty,
        ObjectCount: 0,
        AreaCount: 0,
        AttributeCount: 0,
        HistorizedAttributeCount: 0,
        AlarmAttributeCount: 0);

    /// <summary>Gets a value indicating whether the cache entry contains usable data.</summary>
    public bool HasData => Status is GalaxyCacheStatus.Healthy or GalaxyCacheStatus.Stale;
}
