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

/// <summary>
///     A no-op <see cref="IHistorianDataSource"/> — the server's default historian backend when no
///     real historian has been registered. Every read returns an EMPTY result (no samples / events,
///     null continuation point) so the node-manager's HistoryRead override surfaces
///     <c>GoodNoData</c> for a historized node rather than faulting, and
///     <see cref="GetHealthSnapshot"/> reports a fully-disabled (zeroed, disconnected) snapshot.
///     <para>
///         A process-wide singleton via <see cref="Instance"/> (private ctor): it carries no state
///         and is immutable, so one shared instance is safe to assign as the node-manager's
///         <c>HistorianDataSource</c> default until the Host wires a real source post-start.
///     </para>
/// </summary>
public sealed class NullHistorianDataSource : IHistorianDataSource
{
    /// <summary>The shared singleton instance.</summary>
    public static readonly NullHistorianDataSource Instance = new();

    private static readonly HistoryReadResult EmptyRead = new(Array.Empty<DataValueSnapshot>(), null);
    private static readonly HistoricalEventsResult EmptyEvents = new(Array.Empty<HistoricalEvent>(), null);

    private NullHistorianDataSource()
    {
    }

    /// <inheritdoc />
    public Task<HistoryReadResult> ReadRawAsync(
        string fullReference,
        DateTime startUtc,
        DateTime endUtc,
        uint maxValuesPerNode,
        CancellationToken cancellationToken) => Task.FromResult(EmptyRead);

    /// <inheritdoc />
    public Task<HistoryReadResult> ReadProcessedAsync(
        string fullReference,
        DateTime startUtc,
        DateTime endUtc,
        TimeSpan interval,
        HistoryAggregateType aggregate,
        CancellationToken cancellationToken) => Task.FromResult(EmptyRead);

    /// <inheritdoc />
    public Task<HistoryReadResult> ReadAtTimeAsync(
        string fullReference,
        IReadOnlyList<DateTime> timestampsUtc,
        CancellationToken cancellationToken) => Task.FromResult(EmptyRead);

    /// <inheritdoc />
    public Task<HistoricalEventsResult> ReadEventsAsync(
        string? sourceName,
        DateTime startUtc,
        DateTime endUtc,
        int maxEvents,
        CancellationToken cancellationToken) => Task.FromResult(EmptyEvents);

    /// <inheritdoc />
    public HistorianHealthSnapshot GetHealthSnapshot() => new(
        TotalQueries: 0,
        TotalSuccesses: 0,
        TotalFailures: 0,
        ConsecutiveFailures: 0,
        LastSuccessTime: null,
        LastFailureTime: null,
        LastError: null,
        ProcessConnectionOpen: false,
        EventConnectionOpen: false,
        ActiveProcessNode: null,
        ActiveEventNode: null,
        Nodes: Array.Empty<HistorianClusterNodeState>());

    /// <summary>No-op — the null source owns no unmanaged resources.</summary>
    public void Dispose()
    {
        // Stateless singleton; nothing to release.
    }
}
