#pragma once

#include <cstddef>
#include <memory>
#include <numeric>
#include <vector>

namespace message
{

enum class PayloadType : uint8_t
{
    IPMI = 0x00,
    SOL = 0x01,
    OPEN_SESSION_REQUEST = 0x10,
    OPEN_SESSION_RESPONSE = 0x11,
    RAKP1 = 0x12,
    RAKP2 = 0x13,
    RAKP3 = 0x14,
    RAKP4 = 0x15,
    INVALID = 0xFF,
};

// RMCP Classes of Message as per section 13.1.3.
enum class ClassOfMsg : uint8_t
{
    RESERVED = 0x05,
    ASF = 0x06,
    IPMI = 0x07,
    OEM = 0x08,
};

#ifdef RMCP_PING
// RMCP Message Type as per section 13.1.3.
enum class RmcpMsgType : uint8_t
{
    PING = 0x80,
    PONG = 0x40,
};
#endif // RMCP_PING

namespace LAN
{

constexpr uint8_t requesterBMCAddress = 0x20;
constexpr uint8_t responderBMCAddress = 0x81;

namespace header
{

/**
 * @struct IPMI LAN Message Request Header
 */
struct Request
{
    uint8_t rsaddr;
    uint8_t netfn;
    uint8_t cs;
    uint8_t rqaddr;
    uint8_t rqseq;
    uint8_t cmd;
} __attribute__((packed));

/**
 * @struct IPMI LAN Message Response Header
 */
struct Response
{
    uint8_t rqaddr;
    uint8_t netfn;
    uint8_t cs;
    uint8_t rsaddr;
    uint8_t rqseq;
    uint8_t cmd;
} __attribute__((packed));

} // namespace header

namespace trailer
{

/**
 * @struct IPMI LAN Message Trailer
 */
struct Request
{
    uint8_t checksum;
} __attribute__((packed));

using Response = Request;

} // namespace trailer

} // namespace LAN

/**
 * @brief Calculate 8 bit 2's complement checksum
 *
 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
 * modulo 256. Then checksum = - checksum. When the checksum and the
 * bytes are added together, modulo 256, the result should be 0.
 */
static inline uint8_t crc8bit(const uint8_t* ptr, const size_t len)
{
    return (0x100 - std::accumulate(ptr, ptr + len, 0));
}

/**
 * @struct Message
 *
 * IPMI message is data encapsulated in an IPMI Session packet. The IPMI
 * Session packets are encapsulated in RMCP packets, which are encapsulated in
 * UDP datagrams. Refer Section 13.5 of IPMI specification(IPMI Messages
 * Encapsulation Under RMCP). IPMI payload is a special class of data
 * encapsulated in an IPMI session packet.
 */
struct Message
{
    static constexpr uint32_t MESSAGE_INVALID_SESSION_ID = 0xBADBADFF;

    Message() :
        payloadType(PayloadType::INVALID),
        rcSessionID(Message::MESSAGE_INVALID_SESSION_ID),
        bmcSessionID(Message::MESSAGE_INVALID_SESSION_ID),
        rmcpMsgClass(ClassOfMsg::RESERVED)
    {}

    /**
     * @brief Special behavior for copy constructor
     *
     * Based on incoming message state, the resulting message will have a
     * pre-baked state. This is used to simplify the flows for creating a
     * response message. For each pre-session state, the response message is
     * actually a different type of message. Once the session has been
     * established, the response type is the same as the request type.
     */
    Message(const Message& other) :
        isPacketEncrypted(other.isPacketEncrypted),
        isPacketAuthenticated(other.isPacketAuthenticated),
        payloadType(other.payloadType), rcSessionID(other.rcSessionID),
        bmcSessionID(other.bmcSessionID), rmcpMsgClass(other.rmcpMsgClass)
    {
        // special behavior for rmcp+ session creation
        if (PayloadType::OPEN_SESSION_REQUEST == other.payloadType)
        {
            payloadType = PayloadType::OPEN_SESSION_RESPONSE;
        }
        else if (PayloadType::RAKP1 == other.payloadType)
        {
            payloadType = PayloadType::RAKP2;
        }
        else if (PayloadType::RAKP3 == other.payloadType)
        {
            payloadType = PayloadType::RAKP4;
        }
    }
    Message& operator=(const Message&) = default;
    Message(Message&&) = default;
    Message& operator=(Message&&) = default;
    ~Message() = default;

    /**
     * @brief Extract the command from the IPMI payload
     *
     * @return Command ID in the incoming message
     */
    uint32_t getCommand()
    {
        uint32_t command = 0;

        command |= (static_cast<uint32_t>(payloadType) << 16);
        if (payloadType == PayloadType::IPMI)
        {
            auto request =
                reinterpret_cast<LAN::header::Request*>(payload.data());
            command |= request->netfn << 8;
            command |= static_cast<uint32_t>(request->cmd);
        }
        return command;
    }

    /**
     * @brief Create the response IPMI message
     *
     * The IPMI outgoing message is constructed out of payload and the
     * corresponding fields are populated. For the payload type IPMI, the
     * LAN message header and trailer are added.
     *
     * @param[in] output - Payload for outgoing message
     *
     * @return Outgoing message on success and nullptr on failure
     */
    std::shared_ptr<Message> createResponse(std::vector<uint8_t>& output)
    {
        // SOL packets don't reply; return NULL
        if (payloadType == PayloadType::SOL)
        {
            return nullptr;
        }
        auto outMessage = std::make_shared<Message>(*this);

        if (payloadType == PayloadType::IPMI)
        {
            outMessage->payloadType = PayloadType::IPMI;

            outMessage->payload.resize(sizeof(LAN::header::Response) +
                                       output.size() +
                                       sizeof(LAN::trailer::Response));

            auto reqHeader =
                reinterpret_cast<LAN::header::Request*>(payload.data());
            auto respHeader = reinterpret_cast<LAN::header::Response*>(
                outMessage->payload.data());

            // Add IPMI LAN Message Response Header
            respHeader->rqaddr = reqHeader->rqaddr;
            respHeader->netfn = reqHeader->netfn | 0x04;
            respHeader->cs = crc8bit(&(respHeader->rqaddr), 2);
            respHeader->rsaddr = reqHeader->rsaddr;
            respHeader->rqseq = reqHeader->rqseq;
            respHeader->cmd = reqHeader->cmd;

            auto assembledSize = sizeof(LAN::header::Response);

            // Copy the output by the execution of the command
            std::copy(output.begin(), output.end(),
                      outMessage->payload.begin() + assembledSize);
            assembledSize += output.size();

            // Add the IPMI LAN Message Trailer
            auto trailer = reinterpret_cast<LAN::trailer::Response*>(
                outMessage->payload.data() + assembledSize);
            trailer->checksum = crc8bit(&respHeader->rsaddr, assembledSize - 3);
        }
        else
        {
            outMessage->payload = output;
        }
        return outMessage;
    }

    bool isPacketEncrypted;     // Message's Encryption Status
    bool isPacketAuthenticated; // Message's Authentication Status
    PayloadType payloadType;    // Type of message payload (IPMI,SOL ..etc)
    uint32_t rcSessionID;       // Remote Client's Session ID
    uint32_t bmcSessionID;      // BMC's session ID
    uint32_t sessionSeqNum;     // Session Sequence Number
    ClassOfMsg rmcpMsgClass;    // Class of Message
#ifdef RMCP_PING
    uint8_t asfMsgTag;          // ASF Message Tag
#endif                          // RMCP_PING

    /** @brief Message payload
     *
     *  “Payloads” are a capability specified for RMCP+ that enable an IPMI
     *  session to carry types of traffic that are in addition to IPMI Messages.
     *  Payloads can be ‘standard’ or ‘OEM’.Standard payload types include IPMI
     *  Messages, messages for session setup under RMCP+, and the payload for
     *  the “Serial Over LAN” capability introduced in IPMI v2.0.
     */
    std::vector<uint8_t> payload;
};

} // namespace message
