package com.zb.mom.ww.mxgateway.client;

import mxaccess_gateway.v1.MxaccessGateway.MxCommandReply;
import mxaccess_gateway.v1.MxaccessGateway.ProtocolStatus;

/**
 * Thrown when the gateway accepts an MXAccess command but the command itself
 * fails at the protocol layer. Carries the original {@code MxCommandReply} and
 * {@code ProtocolStatus} so callers can inspect the failure detail.
 */
public class MxGatewayCommandException extends MxGatewayException {
    private final ProtocolStatus protocolStatus;
    private final MxCommandReply reply;

    /**
     * Creates a new command exception.
     *
     * @param operation human-readable name of the failing operation
     * @param protocolStatus protocol status returned by the gateway
     * @param reply raw command reply, or {@code null} when the call failed before a reply was produced
     */
    public MxGatewayCommandException(String operation, ProtocolStatus protocolStatus, MxCommandReply reply) {
        super(MxGatewayErrors.protocolStatusMessage(operation, protocolStatus));
        this.protocolStatus = protocolStatus;
        this.reply = reply;
    }

    /**
     * Creates a new command exception with an already-built, verbatim message.
     * Used to re-surface a failure with a redacted message while preserving the
     * original protocol status and reply.
     *
     * @param message the exact message to surface (already formatted/redacted)
     * @param protocolStatus protocol status returned by the gateway
     * @param reply raw command reply, or {@code null} when none was produced
     * @param cause underlying error, or {@code null}
     */
    protected MxGatewayCommandException(
            String message, ProtocolStatus protocolStatus, MxCommandReply reply, Throwable cause) {
        super(message, cause);
        this.protocolStatus = protocolStatus;
        this.reply = reply;
    }

    /**
     * Returns the gateway protocol status that triggered this exception.
     *
     * @return the protocol status, or {@code null} if none was supplied
     */
    public ProtocolStatus protocolStatus() {
        return protocolStatus;
    }

    /**
     * Returns the raw command reply associated with the failure.
     *
     * @return the command reply, or {@code null} if no reply was available
     */
    public MxCommandReply reply() {
        return reply;
    }
}
