using ZB.MOM.WW.HistorianGateway.Contracts.Grpc;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Mapping;

/// <summary>
/// Maps the driver-agnostic <see cref="HistoryAggregateType"/> (OPC UA Part 13 aggregate) onto the
/// gateway's native <see cref="RetrievalMode"/>.
/// </summary>
/// <remarks>
/// <para>
/// Average/Minimum/Maximum line up with the legacy Wonderware client's aggregate mapping. The two
/// remaining members are now served by <b>native</b> gateway retrieval modes:
/// <see cref="HistoryAggregateType.Total"/> → <see cref="RetrievalMode.Integral"/> and
/// <see cref="HistoryAggregateType.Count"/> → <see cref="RetrievalMode.Counter"/>.
/// </para>
/// <para>
/// This replaces the Wonderware-era client-side workarounds (Total derived as Average × interval,
/// Count approximated from a value count): no client-side scaling is performed any more, so the
/// gateway path is a strict improvement.
/// </para>
/// </remarks>
internal static class AggregateModeMapper
{
    /// <summary>Maps an aggregate function to the gateway retrieval mode.</summary>
    /// <param name="aggregate">The driver-agnostic aggregate function.</param>
    /// <returns>The matching gateway <see cref="RetrievalMode"/>.</returns>
    /// <exception cref="ArgumentOutOfRangeException">A future, unmapped enum member (fails the matrix guard).</exception>
    public static RetrievalMode ToRetrievalMode(HistoryAggregateType aggregate) => aggregate switch
    {
        HistoryAggregateType.Average => RetrievalMode.TimeWeightedAverage,
        HistoryAggregateType.Minimum => RetrievalMode.MinimumWithTime,
        HistoryAggregateType.Maximum => RetrievalMode.MaximumWithTime,
        HistoryAggregateType.Total => RetrievalMode.Integral,
        HistoryAggregateType.Count => RetrievalMode.Counter,
        _ => throw new ArgumentOutOfRangeException(
            nameof(aggregate), aggregate, "Unmapped HistoryAggregateType — add a RetrievalMode mapping."),
    };
}
