#ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
#define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_

#include "SdCardManager.h"
#include "OBSWConfig.h"

#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/memory/HasFileSystemIF.h"

#include <string>
#include <filesystem>

class CoreController;

class FileSystemHandler: public SystemObject,
        public ExecutableObjectIF,
        public HasFileSystemIF {
public:
    struct FsCommandCfg: public FileSystemArgsIF {
        // Can be used to automatically use mount prefix of active SD card.
        // Otherwise, the operator has to specify the full path to the mounted SD card as well.
        bool useMountPrefix = false;
    };

    FileSystemHandler(object_id_t fileSystemHandler);
    virtual~ FileSystemHandler();

    ReturnValue_t performOperation(uint8_t) override;

    ReturnValue_t initialize() override;

    /**
     * Function to get the MessageQueueId_t of the implementing object
     * @return MessageQueueId_t of the object
     */
    MessageQueueId_t getCommandQueue() const override;
    ReturnValue_t appendToFile(const char* repositoryPath,
            const char* filename, const uint8_t* data, size_t size,
            uint16_t packetNumber, FileSystemArgsIF* args = nullptr) override;
    ReturnValue_t createFile(const char* repositoryPath,
            const char* filename, const uint8_t* data = nullptr,
            size_t size = 0, FileSystemArgsIF* args = nullptr) override;
    ReturnValue_t removeFile(const char* repositoryPath,
            const char* filename, FileSystemArgsIF* args = nullptr) override;
    ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname,
            bool createParentDirs, FileSystemArgsIF* args = nullptr) override;
    ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname,
            bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) override;
    ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename,
            const char* newFilename, FileSystemArgsIF* args = nullptr) override;

private:
    CoreController* coreCtrl = nullptr;
    MessageQueueIF* mq = nullptr;
    std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
    static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE;

    SdCardManager* sdcMan = nullptr;
    uint8_t opCounter = 0;

    void fileSystemHandlerLoop();
    void fileSystemCheckup();
    std::filesystem::path getInitPath(FileSystemArgsIF* args);
    void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix);
};



#endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */