#pragma once

#include "message.hpp"
#include "session.hpp"

#include <cstddef>

namespace message
{

namespace parser
{

constexpr size_t RMCP_VERSION = 6;

// RMCP Messages with class=IPMI should be sent with an RMCP Sequence
// Number of FFh to indicate that an RMCP ACK message should not be
// generated by the message receiver.
constexpr size_t RMCP_SEQ = 0xFF;

// RMCP Message Class 7h is for IPMI
constexpr size_t RMCP_MESSAGE_CLASS_IPMI = 7;

// RMCP Session Header Size
constexpr size_t RMCP_SESSION_HEADER_SIZE = 4;

// RMCP/ASF Pong Message ASF Header Data Length
// as per IPMI spec 13.2.4
constexpr size_t RMCP_ASF_PONG_DATA_LEN = 16;

// ASF IANA
constexpr uint32_t ASF_IANA = 4542;

// ASF Supported Entities
constexpr uint32_t ASF_SUPP_ENT = 0x81;

// ASF Supported Entities
constexpr uint32_t ASF_SUPP_INT = 0x00;

// Maximum payload size
constexpr size_t MAX_PAYLOAD_SIZE = 255;

enum class SessionHeader
{
    IPMI15 = 0x00,
    IPMI20 = 0x06,
    INVALID = 0xFF,
};

// RMCP Header
struct RmcpHeader_t
{
    // RMCP Header
    uint8_t version;
    uint8_t reserved;
    uint8_t rmcpSeqNum;
    uint8_t classOfMsg;
} __attribute__((packed));

struct BasicHeader_t
{
    // RMCP Header
    struct RmcpHeader_t rmcp;

    // IPMI partial session header
    union
    {
        uint8_t reserved1 : 4;
        uint8_t authType : 4;
        uint8_t formatType;
    } format;
} __attribute__((packed));

/**
 * @brief Unflatten an incoming packet and prepare the IPMI message
 *
 * @param[in] inPacket - Incoming IPMI packet
 *
 * @return A tuple with IPMI message and the session header type to sent the
 *         response packet. In case of success incoming message and session
 *         header type. In case of failure nullptr and session header type
 *         would be invalid.
 */
std::tuple<std::shared_ptr<Message>, SessionHeader>
    unflatten(std::vector<uint8_t>& inPacket);

/**
 * @brief Flatten an IPMI message and generate the IPMI packet with the
 *        session header
 *
 * @param[in] outMessage - IPMI message to be flattened
 * @param[in] authType - Session header type to be added to the IPMI
 *                       packet
 *
 * @return IPMI packet on success
 */
std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
                             SessionHeader authType,
                             std::shared_ptr<session::Session> session);

} // namespace parser

namespace ipmi15parser
{

struct SessionHeader_t
{
    struct parser::BasicHeader_t base;
    uint32_t sessSeqNum;
    uint32_t sessId;
    // <Optional Field: AuthCode>
    uint8_t payloadLength;
} __attribute__((packed));

struct SessionTrailer_t
{
    uint8_t legacyPad;
} __attribute__((packed));

/**
 * @brief Unflatten an incoming packet and prepare the IPMI message
 *
 * @param[in] inPacket - Incoming IPMI packet
 *
 * @return IPMI message in the packet on success
 */
std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);

/**
 * @brief Flatten an IPMI message and generate the IPMI packet with the
 *        session header
 *
 * @param[in] outMessage - IPMI message to be flattened
 *
 * @return IPMI packet on success
 */
std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
                             std::shared_ptr<session::Session> session);

} // namespace ipmi15parser

namespace ipmi20parser
{

constexpr size_t MAX_INTEGRITY_DATA_LENGTH = 12;
constexpr size_t PAYLOAD_ENCRYPT_MASK = 0x80;
constexpr size_t PAYLOAD_AUTH_MASK = 0x40;

struct SessionHeader_t
{
    struct parser::BasicHeader_t base;

    uint8_t payloadType;

    uint32_t sessId;
    uint32_t sessSeqNum;
    uint16_t payloadLength;
} __attribute__((packed));

struct SessionTrailer_t
{
    // Integrity Pad
    uint8_t padLength;
    uint8_t nextHeader;
} __attribute__((packed));

/**
 * @brief Unflatten an incoming packet and prepare the IPMI message
 *
 * @param[in] inPacket - Incoming IPMI packet
 *
 * @return IPMI message in the packet on success
 */
std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);

/**
 * @brief Flatten an IPMI message and generate the IPMI packet with the
 *        session header
 *
 * @param[in] outMessage - IPMI message to be flattened
 * @param[in] session - session handle
 *
 * @return IPMI packet on success
 */
std::vector<uint8_t> flatten(std::shared_ptr<Message> outMessage,
                             std::shared_ptr<session::Session> session);

namespace internal
{

/**
 * @brief Add sequence number to the message
 *
 * @param[in] packet - outgoing packet to which to add sequence number
 * @param[in] session - session handle
 *
 */
void addSequenceNumber(std::vector<uint8_t>& packet,
                       std::shared_ptr<session::Session> session);

/**
 * @brief Verify the integrity data of the incoming IPMI packet
 *
 * @param[in] packet - Incoming IPMI packet
 * @param[in] message - IPMI Message populated from the incoming packet
 * @param[in] payloadLen - Length of the IPMI payload
 * @param[in] session - session handle
 *
 */
bool verifyPacketIntegrity(const std::vector<uint8_t>& packet,
                           const std::shared_ptr<Message> message,
                           size_t payloadLen,
                           const std::shared_ptr<session::Session>& session);

/**
 * @brief Add Integrity data to the outgoing IPMI packet
 *
 * @param[in] packet - Outgoing IPMI packet
 * @param[in] message - IPMI Message populated for the outgoing packet
 * @param[in] payloadLen - Length of the IPMI payload
 */
void addIntegrityData(std::vector<uint8_t>& packet,
                      const std::shared_ptr<Message> message, size_t payloadLen,
                      const std::shared_ptr<session::Session>& session);

/**
 * @brief Decrypt the encrypted payload in the incoming IPMI packet
 *
 * @param[in] packet - Incoming IPMI packet
 * @param[in] message - IPMI Message populated from the incoming packet
 * @param[in] payloadLen - Length of encrypted IPMI payload
 * @param[in] session - session handle
 *
 * @return on successful completion, return the plain text payload
 */
std::vector<uint8_t>
    decryptPayload(const std::vector<uint8_t>& packet,
                   const std::shared_ptr<Message> message, size_t payloadLen,
                   const std::shared_ptr<session::Session>& session);

/**
 * @brief Encrypt the plain text payload for the outgoing IPMI packet
 *
 * @param[in] message - IPMI Message populated for the outgoing packet
 * @param[in] session - session handle
 *
 * @return on successful completion, return the encrypted payload
 */
std::vector<uint8_t>
    encryptPayload(std::shared_ptr<Message> message,
                   const std::shared_ptr<session::Session>& session);

} // namespace internal

} // namespace ipmi20parser

#ifdef RMCP_PING
namespace asfparser
{

// ASF message fields for RMCP Ping message
struct AsfMessagePing_t
{
    struct parser::RmcpHeader_t rmcp;

    uint32_t iana;
    uint8_t msgType;
    uint8_t msgTag;
    uint8_t reserved;
    uint8_t dataLen;
} __attribute__((packed));

// ASF message fields for RMCP Pong message
struct AsfMessagePong_t
{
    struct AsfMessagePing_t ping;

    uint32_t iana;
    uint32_t oemDefined;
    uint8_t suppEntities;
    uint8_t suppInteract;
    uint32_t reserved1;
    uint16_t reserved2;
} __attribute__((packed));

/**
 * @brief Unflatten an incoming packet and prepare the ASF message
 *
 * @param[in] inPacket - Incoming ASF packet
 *
 * @return ASF message in the packet on success
 */
std::shared_ptr<Message> unflatten(std::vector<uint8_t>& inPacket);

/**
 * @brief Generate the ASF packet with the RMCP header
 *
 * @param[in] asfMsgTag - ASF Message Tag from Ping request
 *
 * @return ASF packet on success
 */
std::vector<uint8_t> flatten(uint8_t asfMsgTag);

} // namespace asfparser
#endif // RMCP_PING

} // namespace message
