#ifndef FILESYSTEM_H
#define FILESYSTEM_H

#include "SpiFlash25.h"
#include "spiffs.h"

/**********************************************************
 * Filesystem Variables, Functions, & Setup
 **********************************************************/
#define FLASH_PAGE_SIZE         256
static uint8_t fs_work_buf[FLASH_PAGE_SIZE * 2];
static uint8_t fs_fds[32 * 2];
static uint8_t fs_cache_buf[(FLASH_PAGE_SIZE + 32) * 4];
// Dragonfly
static SpiFlash25 flash(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS1);
// Nucleo
//static SpiFlash25 flash(D11, D12, D13, D7);
spiffs* fs;
static spiffs _fs;
static spiffs_config fs_cfg;

int spi_read(unsigned int addr, unsigned int size, unsigned char* data) {
    if (flash.read(addr, size, (char*)data))
        return SPIFFS_OK;
    return -1;
}

int spi_write(unsigned int addr, unsigned int size, unsigned char* data) {
    if (flash.write(addr, size, (const char*)data))
        return SPIFFS_OK;
    return -1;
}

int spi_erase(unsigned int addr, unsigned int size) {
    flash.clear_sector(addr);
    return SPIFFS_OK;
}

bool mount_filesystem() {
    fs = &_fs;

    fs_cfg.phys_size = 2*1024*1024;
    fs_cfg.phys_addr = 0;
    fs_cfg.phys_erase_block = 64*1024;
    fs_cfg.log_block_size = 64*1024;
    fs_cfg.log_page_size = FLASH_PAGE_SIZE;

    fs_cfg.hal_read_f = &spi_read;
    fs_cfg.hal_write_f = &spi_write;
    fs_cfg.hal_erase_f = &spi_erase;

    if (SPIFFS_mount(fs, &fs_cfg, fs_work_buf, fs_fds, sizeof(fs_fds), fs_cache_buf, sizeof(fs_cache_buf), NULL)) {
        return false;
    }
    return true;
}

#endif
