/*_############################################################################
  _## 
  _##  SNMP4J - MPv3ScopedPDUExtractor.java  
  _## 
  _##  Copyright (C) 2003-2026  Frank Fock (SNMP4J.org)
  _##  
  _##  Licensed under the Apache License, Version 2.0 (the "License");
  _##  you may not use this file except in compliance with the License.
  _##  You may obtain a copy of the License at
  _##  
  _##      http://www.apache.org/licenses/LICENSE-2.0
  _##  
  _##  Unless required by applicable law or agreed to in writing, software
  _##  distributed under the License is distributed on an "AS IS" BASIS,
  _##  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  _##  See the License for the specific language governing permissions and
  _##  limitations under the License.
  _##  
  _##########################################################################*/
package org.snmp4j.mp;

import org.snmp4j.ScopedPDU;
import org.snmp4j.TransportStateReference;
import org.snmp4j.asn1.BERInputStream;
import org.snmp4j.asn1.BEROutputStream;
import org.snmp4j.security.SecurityModel;
import org.snmp4j.security.SecurityParameters;
import org.snmp4j.security.SecurityStateReference;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OctetString;

import java.io.IOException;

/**
 * Interface defining the mechanism to extract the ScopedPDU from an SNMPv3 message.
 * The extraction process involves dissecting the whole SNMP message, applying security models,
 * and converting the necessary parts into a ScopedPDU.
 * @since 3.9.0
 * @version 3.9.2
 */
public interface MPv3ScopedPDUExtractor {

    /**
     * Use a security model to extract the scoped PDU from the wholeMsg and return state information.
     * @param wholeMsg
     *    the incoming SNMP message with position at the beginning of the scoped PDU.
     * @param secModel
     *    the security model to be used.
     * @param tmStateReference
     *    the already collected transport model state reference.
     * @param header
     *    provides the message length data from the already read message header.
     * @param securityLevel
     *    the target security level.
     * @param maxSizeResponseScopedPDU
     *    returns the maximum size of the response PDU allowed for this security model.
     * @param statusInformation
     *    returns the status information
     * @param securityName
     *    returns the extracted security name used to authenticate/encrypt the message.
     * @param securityEngineID
     *    returns the security engine ID
     * @param snmpVersion
     *    returns the SNMP version
     * @param secParameters
     *    returns the security parameters.
     * @param scopedPDU
     *    returns the scoped PDU.
     * @param secStateReference
     *    returns security state reference.
     * @return
     *    the status of the operation.
     *    See {@link SecurityModel#processIncomingMsg(int, int, SecurityParameters, SecurityModel, int, BERInputStream,
     *    TransportStateReference, OctetString, OctetString, BEROutputStream, Integer32, SecurityStateReference,
     *    StatusInformation)}
     * @throws IOException
     *    on fatal encoding errors.
     * @since 3.9.0
     */
    int extractScopedPDU(BERInputStream wholeMsg, SecurityModel secModel,
                         TransportStateReference tmStateReference, MPv3.HeaderData header,
                         Integer32 securityLevel,
                         Integer32 maxSizeResponseScopedPDU, StatusInformation statusInformation,
                         OctetString securityName, OctetString securityEngineID,
                         Integer32 snmpVersion,
                         SecurityParameters secParameters,
                         BEROutputStream scopedPDU, SecurityStateReference secStateReference) throws IOException;

    /**
     * Validates the prepared PDU (Protocol Data Unit) for conformance to SNMPv3 message processing.
     * This method performs various checks to ensure the received or prepared PDU is consistent
     * with the expected values as per SNMPv3 specifications.
     *
     * @param securityName          The security name representing the user or entity.
     * @param securityLevel         The security level of the message (e.g., noAuthNoPriv, authNoPriv, authPriv).
     * @param scopedPdu             The SNMP ScopedPDU to be validated.
     * @param header                The SNMP HeaderData containing metadata like message ID.
     * @param securityEngineID      The security engine ID of the sender or receiver.
     * @param secModel              The SecurityModel used to process the PDU.
     * @param stateReference        State reference associated with the message.
     * @param secStateReference     The SecurityStateReference associated with processing.
     * @param sendPduHandle         The handle used to track the PDU being sent.
     * @param mutableStateReference The mutable state reference for updating internal state during processing.
     * @param statusInformation     The status information in case of errors or processing outcomes.
     * @return An integer value indicating the result of the validation:
     *         - {@code SnmpConstants.SNMP_MP_OK} if the validation is successful.
     *         - {@code SnmpConstants.SNMP_MP_MATCH_ERROR} if the received message does not match the expected cached values.
     *         - {@code SnmpConstants.SNMP_MP_UNKNOWN_MSGID} if the message ID could not be found in the cache.
     *         - {@code SnmpConstants.SNMP_MP_INVALID_ENGINEID} if the security engine ID does not match the local engine ID.
     *         - {@code SnmpConstants.SNMP_MP_DOUBLED_MESSAGE} if a duplicate message is detected.
     *         - {@code null} if the validation fails undefined and processing cannot continue.
     * @since 3.9.2
     */
    default <A extends Address> Integer validatePreparedPDU(OctetString securityName,
                                                            Integer32 securityLevel,
                                                            ScopedPDU scopedPdu,
                                                            MPv3.HeaderData header,
                                                            OctetString securityEngineID,
                                                            SecurityModel secModel,
                                                            StateReference<A> stateReference,
                                                            SecurityStateReference secStateReference,
                                                            PduHandle sendPduHandle,
                                                            MutableStateReference<A> mutableStateReference,
                                                            StatusInformation statusInformation) {
        return SnmpConstants.SNMP_MP_OK;
    }

}
