using ZB.MOM.WW.Audit;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;

namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;

/// <summary>
/// Maps the ScadaBridge (<see cref="AuditStatus"/>, <see cref="AuditKind"/>) pair onto
/// the canonical <see cref="AuditOutcome"/> required by <c>ZB.MOM.WW.Audit.AuditEvent</c>.
/// </summary>
/// <remarks>
/// <para>Projection table:</para>
/// <list type="bullet">
///   <item><see cref="AuditKind.InboundAuthFailure"/> → <see cref="AuditOutcome.Denied"/>
///     (checked <b>first</b>, overrides any status).</item>
///   <item><see cref="AuditStatus.Delivered"/> → <see cref="AuditOutcome.Success"/>.</item>
///   <item><see cref="AuditStatus.Failed"/>, <see cref="AuditStatus.Parked"/>,
///     <see cref="AuditStatus.Discarded"/> → <see cref="AuditOutcome.Failure"/>.</item>
///   <item>All other statuses (<c>Submitted</c>, <c>Forwarded</c>, <c>Attempted</c>,
///     <c>Skipped</c>) → <see cref="AuditOutcome.Success"/>.</item>
/// </list>
/// </remarks>
public static class AuditOutcomeProjector
{
    /// <summary>
    /// Projects <paramref name="status"/> + <paramref name="kind"/> onto the canonical
    /// <see cref="AuditOutcome"/>.
    /// </summary>
    /// <param name="status">The audit status of the operation.</param>
    /// <param name="kind">The audit kind; <see cref="AuditKind.InboundAuthFailure"/> takes precedence over status.</param>
    /// <returns>The projected <see cref="AuditOutcome"/> value.</returns>
    public static AuditOutcome Project(AuditStatus status, AuditKind kind)
    {
        // Auth-failure kind takes absolute precedence — checked before any status rule.
        if (kind == AuditKind.InboundAuthFailure)
            return AuditOutcome.Denied;

        return status switch
        {
            AuditStatus.Delivered  => AuditOutcome.Success,
            AuditStatus.Failed     => AuditOutcome.Failure,
            AuditStatus.Parked     => AuditOutcome.Failure,
            AuditStatus.Discarded  => AuditOutcome.Failure,
            // Submitted / Forwarded / Attempted / Skipped → in-progress or short-circuit → Success
            _                      => AuditOutcome.Success,
        };
    }
}
