#pragma once

#include "base.hpp"
#include "platform.hpp"
#include "pldmd/handler.hpp"

#include <libpldm/file.h>

#include <fstream>
#include <functional>
#include <map>
#include <string>
#include <string_view>

namespace pldm
{
namespace responder
{
namespace file_transfer
{

struct FileDescriptor
{
    FILE* fp;
    uint32_t fileSize;
    uint32_t startingOffset;
    uint32_t sectionLength;
    uint32_t prevChecksum;
    uint16_t fileIdentifier;
};

/**
 * @brief Reads a specified portion of a file
 *
 * @param fp An open file pointer.
 * @param fileSize The total size of the file in bytes.
 * @param offset The starting position from where to read in the file stream.
 * @param readSize The number of bytes to read from the offset.
 * @param data_ptr Pointer to the buffer to store data. At minimum buffer size
 * should be readSize.
 * @return 0 if successful else -1.
 */
int fileRead(FILE* fp, uint32_t fileSize, uint32_t offset, uint32_t readSize,
             uint8_t* dataPtr);

class Handler : public CmdHandler
{
  public:
    Handler(responder::base::Handler* baseHandler,
            responder::platform::Handler* platformHandler);

  private:
    /**
     * @brief Returns a free file descriptor
     */
    std::optional<uint16_t> getFreeFileDescriptor(uint16_t fileIdentifier);

    /**
     * @brief Removes a file descriptor from fileDescriptors
     */
    void removeFileDescriptor(uint16_t fileDescriptor);

    /**
     * @brief Handler for the DfOpen command
     */
    Response dfOpen(const pldm_msg* request, size_t payloadLength);

    /**
     * @brief Handler for the DfClose command
     */
    Response dfClose(const pldm_msg* request, size_t payloadLength);

    /**
     * @brief Calculates the data length and transfer flag for a DfRead response
     */
    uint32_t getDataLengthBytesAndTransferFlag(
        const FileDescriptor& fileDescriptor, uint32_t currOffset,
        uint16_t multipartSize, uint8_t* transferFlag);

    /**
     * @brief Calculates the next offset for a DfRead response
     */
    uint32_t getNextOffset(uint32_t currOffset, uint32_t dataLengthBytes);

    /**
     * @brief Creates a DfRead response message
     */
    Response createReadResponse(
        const pldm_msg* request,
        const pldm_base_multipart_receive_req& decodedReq,
        FileDescriptor& fileDescriptor, uint32_t currentTransferHandle,
        uint8_t transferFlag, uint32_t nextTransferHandle,
        uint32_t dataLengthBytes);

    /**
     * @brief Handles the first part of a DfRead transfer
     */
    Response dfReadTransferFirstPart(
        const pldm_msg* request,
        const pldm_base_multipart_receive_req& decodedReq,
        uint16_t multipartSize, FileDescriptor& fileDescriptor);

    /**
     * @brief Handles the current or next part of a DfRead transfer
     */
    Response dfReadTransferCurrentOrNextPart(
        const pldm_msg* request,
        const pldm_base_multipart_receive_req& decodedReq,
        uint16_t multipartSize, FileDescriptor& fileDescriptor);

    /**
     * @brief Handles the completion or abort of a DfRead transfer
     */
    Response dfReadTransferCompleteOrAbort(
        const pldm_msg* request,
        const pldm_base_multipart_receive_req& decodedReq,
        uint16_t multipartSize, FileDescriptor& fileDescriptor);

    /**
     * @brief Handler for the DfRead command
     */
    Response dfRead(pldm_tid_t tid, const pldm_msg* request,
                    size_t payloadLength);

    Response handleMultipartReceive(pldm_tid_t tid, const pldm_msg* request,
                                    size_t reqMsgLen) override;

    responder::base::Handler* baseHandler;

    // PLDM Platform type handler. File pointers will be initialized during file
    // PDR descriptor handling. So This will allow the file transfer handler to
    // get the FILE pointers from platform handler.
    responder::platform::Handler* platformHandler;

    // Store active file descriptors
    std::map<uint16_t, FileDescriptor> fileDescriptors;

    // This value will be incremented each time a new file descriptor is
    // created. This is the simplest approach. We could change this later if we
    // need a better approach.
    uint16_t nextFileDescriptor;
};

} // namespace file_transfer
} // namespace responder
} // namespace pldm
