#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(const std::shared_ptr<Message>& outMessage,
                             SessionHeader authType,
                             const 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(const std::shared_ptr<Message>& outMessage,
                             const 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(const std::shared_ptr<Message>& outMessage,
                             const 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,
                       const 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(const 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
