#ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
#define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_

#include <filesystem>
#include <string>

#include "OBSWConfig.h"
#include "SdCardManager.h"
#include "eive/definitions.h"
#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/memory/HasFileSystemIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/tasks/ExecutableObjectIF.h"

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_ */