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

/// <summary>
///     Server-side historian data source. Registered with the server's history router
///     and resolved per OPC UA namespace, independent of any driver's lifecycle.
/// </summary>
/// <remarks>
///     Distinct from <see cref="IHistoryProvider"/>:
///     <list type="bullet">
///       <item><see cref="IHistoryProvider"/> is a *driver capability* — the server
///         dispatches to it via the driver instance.</item>
///       <item><see cref="IHistorianDataSource"/> is a *server registration* — the
///         server resolves it via namespace and calls it directly, so a single
///         historian (e.g. Wonderware) can serve many drivers' nodes, and drivers can
///         restart without dropping history availability.</item>
///     </list>
///     All values returned use the shared <see cref="DataValueSnapshot"/> /
///     <see cref="HistoricalEvent"/> shapes; backend-specific quality / type encodings
///     are translated to OPC UA <c>StatusCode</c> uints inside the data source.
/// </remarks>
public interface IHistorianDataSource : IDisposable
{
    /// <summary>
    ///     Read raw historical samples for a single tag over a time range.
    /// </summary>
    /// <param name="fullReference">The full reference of the tag to read.</param>
    /// <param name="startUtc">The start of the time range in UTC.</param>
    /// <param name="endUtc">The end of the time range in UTC.</param>
    /// <param name="maxValuesPerNode">The maximum number of values to return per node.</param>
    /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
    /// <returns>The raw historical samples for the tag over the requested range.</returns>
    Task<HistoryReadResult> ReadRawAsync(
        string fullReference,
        DateTime startUtc,
        DateTime endUtc,
        uint maxValuesPerNode,
        CancellationToken cancellationToken);

    /// <summary>
    ///     Read processed (interval-bucketed) samples — average / min / max / count / etc.
    ///     A bucket with no source data returns a sample whose
    ///     <see cref="DataValueSnapshot.StatusCode"/> indicates BadNoData.
    /// </summary>
    /// <param name="fullReference">The full reference of the tag to read.</param>
    /// <param name="startUtc">The start of the time range in UTC.</param>
    /// <param name="endUtc">The end of the time range in UTC.</param>
    /// <param name="interval">The interval for bucketing samples.</param>
    /// <param name="aggregate">The aggregation function to apply to each bucket.</param>
    /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
    /// <returns>One aggregated sample per interval bucket over the requested range.</returns>
    Task<HistoryReadResult> ReadProcessedAsync(
        string fullReference,
        DateTime startUtc,
        DateTime endUtc,
        TimeSpan interval,
        HistoryAggregateType aggregate,
        CancellationToken cancellationToken);

    /// <summary>
    ///     Read one sample per requested timestamp — OPC UA HistoryReadAtTime service.
    ///     Implementations interpolate or return prior-boundary samples per their
    ///     backend's policy. The returned list MUST be the same length and order as
    ///     <paramref name="timestampsUtc"/>; gaps are returned as Bad-quality snapshots.
    /// </summary>
    /// <param name="fullReference">The full reference of the tag to read.</param>
    /// <param name="timestampsUtc">The list of timestamps to read values at.</param>
    /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
    /// <returns>One sample per requested timestamp, in the same order as <paramref name="timestampsUtc"/>.</returns>
    Task<HistoryReadResult> ReadAtTimeAsync(
        string fullReference,
        IReadOnlyList<DateTime> timestampsUtc,
        CancellationToken cancellationToken);

    /// <summary>
    ///     Read historical alarm / event records — OPC UA HistoryReadEvents service.
    ///     Distinct from any live event stream; sources here come from the historian's
    ///     event log. <paramref name="sourceName"/> is null to return all sources.
    /// </summary>
    /// <remarks>
    ///     Note on parameter types — <paramref name="maxEvents"/> is <see cref="int"/> (not
    ///     <see cref="uint"/>) so callers can pass <c>0</c> or a negative value as a "use the
    ///     backend's default cap" sentinel; see <c>WonderwareHistorianClient</c> /
    ///     <c>HistorianDataSource</c> for the rationale. The sibling
    ///     <see cref="ReadRawAsync"/> / <see cref="ReadProcessedAsync"/> use
    ///     <c>uint maxValuesPerNode</c> because their OPC UA HistoryRead surface has no
    ///     equivalent "use default" sentinel.
    ///
    ///     This surface declares <see cref="ReadAtTimeAsync"/> and <see cref="ReadEventsAsync"/>
    ///     as required members — a server-side historian owns the full read surface, unlike
    ///     <see cref="IHistoryProvider"/> where the same two methods are optional default-impl
    ///     methods so legacy drivers can stay raw-only. The asymmetry is intentional.
    /// </remarks>
    /// <param name="sourceName">The source name to filter events, or null to return events from all sources.</param>
    /// <param name="startUtc">The start of the time range in UTC.</param>
    /// <param name="endUtc">The end of the time range in UTC.</param>
    /// <param name="maxEvents">
    ///     The maximum number of events to return. A non-positive value uses the backend's
    ///     default cap. When the backend cap truncates the result, implementations MUST set
    ///     <see cref="HistoricalEventsResult.ContinuationPoint"/> to a non-null token so
    ///     callers can detect truncation and page — a null continuation point means all
    ///     matching events were returned.
    /// </param>
    /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
    /// <returns>The matching historical event records, with a continuation point if the result was truncated.</returns>
    Task<HistoricalEventsResult> ReadEventsAsync(
        string? sourceName,
        DateTime startUtc,
        DateTime endUtc,
        int maxEvents,
        CancellationToken cancellationToken);

    /// <summary>
    ///     Point-in-time health snapshot for diagnostics and dashboards. Pure
    ///     observation; never blocks on backend I/O.
    /// </summary>
    /// <returns>The current health snapshot for the historian backend.</returns>
    HistorianHealthSnapshot GetHealthSnapshot();
}
