#pragma once

#include "external_storer_interface.hpp"
#include "libbej/bej_decoder_json.hpp"
#include "rde_dictionary_manager.hpp"

#include <cstdint>
#include <span>
#include <string_view>

namespace bios_bmc_smm_error_logger
{
namespace rde
{

/**
 * @brief Supported RDE commands.
 *
 * The values used are the same as what BIOS uses.
 */
enum class RdeCommandType : char
{
    // Used for RDE BEJ dictionary transfer.
    RdeMultiPartReceiveResponse = 1,
    // Used for RDE BEJ encoded data.
    RdeOperationInitRequest = 2,
};

/**
 * @brief Used to keep track of RdeMultiPartReceiveResponse START flag
 * reception.
 */
enum class RdeDictTransferFlagState
{
    RdeStateIdle,
    RdeStateStartRecvd,
};

/**
 * @brief Status of RDE command processing.
 */
enum class RdeDecodeStatus
{
    RdeOk,
    RdeInvalidCommand,
    RdeUnsupportedOperation,
    RdeNoDictionary,
    RdePayloadOverflow,
    RdeBejDecodingError,
    RdeInvalidPktOrder,
    RdeDictionaryError,
    RdeFileCreationFailed,
    RdeExternalStorerError,
    // This implies that the stop flag has been received.
    RdeInvalidChecksum,
    // This implies that the checksum is correct.
    RdeStopFlagReceived,
};

enum class RdeOperationInitType : uint8_t
{
    RdeOpInitOperationHead = 0,
    RdeOpInitOperationRead = 1,
    RdeOpInitOperationCreate = 2,
    RdeOpInitOperationDelete = 3,
    RdeOpInitOperationUpdate = 4,
    RdeOpInitOperationReplace = 5,
    RdeOpInitOperationAction = 6,
};

enum class RdeMultiReceiveTransferFlag : uint8_t
{
    RdeMRecFlagStart = 0,
    RdeMRecFlagMiddle = 1,
    RdeMRecFlagEnd = 2,
    RdeMRecFlagStartAndEnd = 3,
};

/**
 * @brief RDEOperationInit response header.
 *
 * BIOS uses this header to send the BEJ encoded data.
 */
struct RdeOperationInitReqHeader
{
    uint32_t resourceID;
    uint16_t operationID;
    uint8_t operationType;

    // OperationFlags bits
    uint8_t locatorValid:1;
    uint8_t containsRequestPayload:1;
    uint8_t containsCustomRequestParameters:1;

    uint8_t reserved:5;
    uint32_t sendDataTransferHandle;
    uint8_t operationLocatorLength;
    uint32_t requestPayloadLength;
} __attribute__((__packed__));

/**
 * @brief RDEMultipartReceive response header.
 *
 * BIOS uses this header to send the BEJ dictionary data.
 */
struct MultipartReceiveResHeader
{
    uint8_t completionCode;
    uint8_t transferFlag;
    uint32_t nextDataTransferHandle;
    uint32_t dataLengthBytes;
} __attribute__((__packed__));

/**
 * @brief Handles RDE messages from the BIOS - BMC circular buffer and updates
 * ExternalStorer.
 */
class RdeCommandHandler
{
  public:
    /**
     * @brief Constructor for RdeExternalStorer.
     *
     * @param[in] exStorer - valid ExternalStorerInterface. This class will take
     * the ownership of this object.
     */
    explicit RdeCommandHandler(
        std::unique_ptr<ExternalStorerInterface> exStorer);

    /**
     * @brief Decode a RDE command.
     *
     * @param[in] rdeCommand - RDE command.
     * @param[in] type - RDE command type.
     * @return RdeDecodeStatus code.
     */
    RdeDecodeStatus decodeRdeCommand(std::span<const uint8_t> rdeCommand,
                                     RdeCommandType type);

    /**
     * @brief Get the number of complete dictionaries received.
     *
     * @return number of complete dictionaries.
     */
    uint32_t getDictionaryCount();

  private:
    /**
     * @brief This keeps track of whether we received the dictionary start flag
     * or not.
     */
    RdeDictTransferFlagState flagState;

    std::unique_ptr<ExternalStorerInterface> exStorer;

    /**
     * @brief We are using the prevDictResourceId to detect a new dictionary.
     *
     * BIOS-BMC buffer uses RdeMultiPartReceiveResponse START flag to indicate
     * the first dictionary data chunk. BMC will not receive this flag at start
     * of every new dictionary but only for the first data chunk. Therefore
     * difference between resource ID is used to identify a new dictionary
     * start. prevDictResourceId keeps track of the resource ID of the last
     * dictionary data chunk.
     */
    uint32_t prevDictResourceId;

    DictionaryManager dictionaryManager;
    libbej::BejDecoderJson decoder;

    uint32_t crc;
    std::array<uint32_t, UINT8_MAX + 1> crcTable;

    /**
     * @brief Handles OperationInit request messages.
     *
     * @param[in] rdeCommand - RDE command.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus operationInitRequest(std::span<const uint8_t> rdeCommand);

    /**
     * @brief Handles MultiPartReceive response messages.
     *
     * @param[in] rdeCommand - RDE command.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus multiPartReceiveResp(std::span<const uint8_t> rdeCommand);

    /**
     * @brief Initializes the CRC table.
     */
    void calcCrcTable();

    /**
     * @brief Update the existing CRC using the provided byte stream.
     *
     * According to the RDE BEJ specification: "32-bit CRC for the entire block
     * of data (all parts concatenated together, excluding this checksum)".
     * Therefore when calculating the CRC whole RDEMultipartReceive Response
     * data packet is considered, not just the dictionary data contained within
     * it.
     *
     * @param[in] stream - a byte stream.
     */
    void updateCrc(std::span<const uint8_t> stream);

    /**
     * @brief Get the final checksum value.
     *
     * @return uint32_t - final checksum value.
     */
    uint32_t finalChecksum();

    /**
     * @brief Process received CRC field from a multi receive response command.
     * END or START_AND_END flag should be set in the command.
     *
     * @param multiReceiveRespCmd - payload with a checksum field populated.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus handleCrc(std::span<const uint8_t> multiReceiveRespCmd);

    /**
     * @brief Handle dictionary data with flag Start.
     *
     * @param[in] header -  RDE header portion of the RDE command.
     * @param[in] data - data portion of the RDE command.
     * @param[in] resourceId - PDR resource ID of the dictionary.
     */
    void handleFlagStart(const MultipartReceiveResHeader* header,
                         const uint8_t* data, uint32_t resourceId);

    /**
     * @brief Handle dictionary data with flag Middle.
     *
     * @param[in] header -  RDE header portion of the RDE command.
     * @param[in] data - data portion of the RDE command.
     * @param[in] resourceId - PDR resource ID of the dictionary.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus handleFlagMiddle(const MultipartReceiveResHeader* header,
                                     const uint8_t* data, uint32_t resourceId);
    /**
     * @brief Handle dictionary data with flag End.
     *
     * @param[in] rdeCommand - RDE command.
     * @param[in] header -  RDE header portion of the RDE command.
     * @param[in] data - data portion of the RDE command.
     * @param[in] resourceId - PDR resource ID of the dictionary.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus handleFlagEnd(std::span<const uint8_t> rdeCommand,
                                  const MultipartReceiveResHeader* header,
                                  const uint8_t* data, uint32_t resourceId);

    /**
     * @brief Handle dictionary data with flag StartAndEnd.
     *
     * @param[in] rdeCommand - RDE command.
     * @param[in] header -  RDE header portion of the RDE command.
     * @param[in] data - data portion of the RDE command.
     * @param[in] resourceId - PDR resource ID of the dictionary.
     * @return RdeDecodeStatus
     */
    RdeDecodeStatus
        handleFlagStartAndEnd(std::span<const uint8_t> rdeCommand,
                              const MultipartReceiveResHeader* header,
                              const uint8_t* data, uint32_t resourceId);
};

} // namespace rde
} // namespace bios_bmc_smm_error_logger
