#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;
    pldm_tid_t tid;
    uint32_t index;
    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();

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

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

    /**
     * @brief Handler for the DfClose command
     */
    Response dfClose(pldm_tid_t tid, 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
