namespace Mbproxy.Proxy;

/// <summary>
/// Direction of a Modbus PDU being processed by the pipeline.
/// </summary>
public enum MbapDirection
{
    /// <summary>A request frame travelling from an upstream client to the backend PLC.</summary>
    RequestToBackend,

    /// <summary>A response frame travelling from the backend PLC back to the upstream client.</summary>
    ResponseToClient,
}

/// <summary>
/// Per-pair context carried through each PDU pipeline call.
/// Phase 03: carries only <see cref="PlcName"/>.
/// Phase 04 extends this via <see cref="PerPlcContext"/>, which carries the BcdTagMap,
/// counters, and logger. Phase 09 added the per-call <c>CurrentRequest</c> slot to
/// <see cref="PerPlcContext"/> for multiplexer-aware response correlation.
/// </summary>
public class PduContext
{
    /// <summary>The configured PLC name (from <c>MbproxyOptions.Plcs[i].Name</c>).</summary>
    public string PlcName { get; init; } = "";
    // Phase 04 adds: BcdTagMap, counters, logger
}

/// <summary>
/// Hook contract for inspecting and rewriting Modbus PDU bytes inline.
/// Called once per frame in each direction (request and response).
///
/// Implementations must be safe to call concurrently from multiple connection pairs.
/// In Phase 03 the only implementation is <see cref="NoopPduPipeline"/> (pass-through).
/// Phase 04 replaces it with a BCD rewriter registered via DI.
/// </summary>
public interface IPduPipeline
{
    /// <summary>
    /// Processes a single Modbus PDU. Implementations may mutate <paramref name="pdu"/> in place.
    /// </summary>
    /// <param name="direction">Whether this is a request or a response frame.</param>
    /// <param name="mbapHeader">The 7-byte MBAP header (read-only; includes TxId, UnitId, FC is in pdu[0]).</param>
    /// <param name="pdu">The PDU bytes starting at the function code. May be mutated in place.</param>
    /// <param name="context">Per-pair context (PLC name; extended in phase 04).</param>
    void Process(MbapDirection direction, ReadOnlySpan<byte> mbapHeader, Span<byte> pdu, PduContext context);
}
