#pragma once

#include "blob_interface.hpp"
#include "ipmi_interface.hpp"

namespace ipmiblob
{

class BlobHandler : public BlobInterface
{
  public:
    enum BlobOEMCommands
    {
        bmcBlobGetCount = 0,
        bmcBlobEnumerate = 1,
        bmcBlobOpen = 2,
        bmcBlobRead = 3,
        bmcBlobWrite = 4,
        bmcBlobCommit = 5,
        bmcBlobClose = 6,
        bmcBlobDelete = 7,
        bmcBlobStat = 8,
        bmcBlobSessionStat = 9,
        bmcBlobWriteMeta = 10,
    };

    explicit BlobHandler(IpmiInterface* ipmi) : ipmi(ipmi){};

    /**
     * Retrieve the blob count.
     *
     * @return the number of blob_ids found (0 on failure).
     */
    int getBlobCount();

    /**
     * Given an index into the list of blobs, return the name.
     *
     * @param[in] index - the index into the list of blob ids.
     * @return the name as a string or empty on failure.
     */
    std::string enumerateBlob(std::uint32_t index);

    /**
     * @throws BlobException.
     */
    void writeMeta(std::uint16_t session, std::uint32_t offset,
                   const std::vector<std::uint8_t>& bytes) override;

    /**
     * @throw BlobException.
     */
    void writeBytes(std::uint16_t session, std::uint32_t offset,
                    const std::vector<std::uint8_t>& bytes) override;

    std::vector<std::string> getBlobList() override;

    /**
     * @throws BlobException.
     */
    StatResponse getStat(const std::string& id) override;

    /**
     * @throws BlobException.
     */
    StatResponse getStat(std::uint16_t session) override;

    /**
     * @throws BlobException.
     */
    std::uint16_t openBlob(const std::string& id,
                           std::uint16_t handlerFlags) override;

    void closeBlob(std::uint16_t session) override;

    /**
     * @throws BlobException.
     */
    std::vector<std::uint8_t> readBytes(std::uint16_t session,
                                        std::uint32_t offset,
                                        std::uint32_t length) override;

  private:
    /**
     * Send the contents of the payload to IPMI, this method handles wrapping
     * with the OEN, subcommand and CRC.
     *
     * @param[in] command - the blob command.
     * @param[in] payload - the payload bytes.
     * @return the bytes returned from the ipmi interface.
     * @throws BlobException.
     */
    std::vector<std::uint8_t>
        sendIpmiPayload(BlobOEMCommands command,
                        const std::vector<std::uint8_t>& payload);

    /**
     * Generic blob byte writer.
     *
     * @param[in] command - the command associated with this write.
     * @param[in] session - the session id.
     * @param[in] offset - the offset for the metadata to write.
     * @param[in] bytes - the bytes to send.
     * @throws BlobException on failure.
     */
    void writeGeneric(BlobOEMCommands command, std::uint16_t session,
                      std::uint32_t offset,
                      const std::vector<std::uint8_t>& bytes);

    /**
     * Generic stat reader.
     *
     * @param[in] command - the command associated with this write.
     * @param[in] request - the bytes of the request
     * @return the metadata StatResponse
     * @throws BlobException on failure.
     */
    StatResponse statGeneric(BlobOEMCommands command,
                             const std::vector<std::uint8_t>& request);

    IpmiInterface* ipmi;
};

} // namespace ipmiblob
