void FS_format()
{
  snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_formatting);
  sendLog(logBuf, LOGLEVEL_INFO);
  LittleFS.format();
  sendLog(F("FS formatted")); 
  File f = LittleFS.open("/formatted", "w");
  if (!f)
  {
    snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_formatFailed);
    sendLog(logBuf, LOGLEVEL_INFO);
  }
  else {
    snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_formatComplete);
    sendLog(logBuf, LOGLEVEL_INFO);
  }
  f.close();
}



void FS_formatIfIsnt()
{
  if (!LittleFS.exists("/formatted"))
  {
    FS_format();
  }
}



void FS_listFiles()
{
  snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_ls);
  sendLog(logBuf);

  Dir _dir = LittleFS.openDir("/");
  while (_dir.next())
  {
    File _f = _dir.openFile("r"); 
    uint16_t _size = _f.size();
    uint8_t _fnLen = strlen(_dir.fileName().c_str());
    char _spaces[42];
    uint8_t _iMax = 0;
    for(uint8_t _i=0; _i < (31 - _fnLen); _i++) {
      _spaces[_i] = ' ';
      _iMax = _i;
    }
    if(_size < 10) {
      _spaces[_iMax +1] = ' ';
      _spaces[_iMax +2] = ' ';
      _spaces[_iMax +3] = ' ';
      _iMax += 3;
    }
    else if(_size < 100) {
      _spaces[_iMax +1] = ' ';
      _spaces[_iMax +2] = ' ';
      _iMax += 2;
    }
    else if(_size < 1000) {
      _spaces[_iMax +1] = ' ';
      _iMax += 1;
    }
    _spaces[_iMax +1] = '\0';

    snprintf(logBuf, LOG_BUFFER_SIZE, "  %s%s%d ", _dir.fileName().c_str(), _spaces, _size);
    sendLog(logBuf);
    _f.close();
  }
  FS_getInfo();
  snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_ls_info, fs_info.usedBytes, fs_info.totalBytes);
  sendLog(logBuf);
  snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_console_line_hr);
  sendLog(logBuf);
}



// code snippet from https://42project.net/esp8266-webserverinhalte-wie-bilder-png-und-jpeg-aus-dem-internen-flash-speicher-laden/
bool FS_downloadFile(String _path, bool _download=false){
  String _dataType = "text/plain";
  //if(path.endsWith("/")) path += "index.htm";
  //if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
  if(_download) _dataType = "application/octet-stream";
  else if(_path.endsWith(".html")) _dataType = "text/html";
  else if(_path.endsWith(".htm")) _dataType = "text/html";
  else if(_path.endsWith(".css")) _dataType = "text/css";
  else if(_path.endsWith(".js")) _dataType = "application/javascript";
  else if(_path.endsWith(".json")) _dataType = "application/json";
  else if(_path.endsWith(".png")) _dataType = "image/png";
  else if(_path.endsWith(".gif")) _dataType = "image/gif";
  else if(_path.endsWith(".jpg")) _dataType = "image/jpeg";
  else if(_path.endsWith(".ico")) _dataType = "image/x-icon";
  else if(_path.endsWith(".xml")) _dataType = "text/xml";
  else if(_path.endsWith(".pdf")) _dataType = "application/pdf";
  else if(_path.endsWith(".zip")) _dataType = "application/zip";
  else if(_path.endsWith(".hex")) _dataType = "application/octet-stream";
  else if(_path.endsWith(".bin")) _dataType = "application/octet-stream";
  File _dataFile = LittleFS.open(_path.c_str(), "r");
  
  // send filename header
  char _contentHeader[71];
  sprintf(_contentHeader, "attachment; filename=\"%s\";", _path.c_str());
  httpServer.sendHeader("Content-Disposition", _contentHeader);

  if (httpServer.streamFile(_dataFile, _dataType) != _dataFile.size()) {
  }
  _dataFile.close();
  return true;
}



bool FS_deleteFile(String _path) {
    if(LittleFS.exists(_path)) {
        LittleFS.remove(_path);
        snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_del, _path.c_str());
        sendLog(logBuf);
        return true;
    }
    else {
        snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_del_error, _path.c_str());
        sendLog(logBuf);
        return false;
    }
}



bool FS_renameFile(String _pathFrom, String _pathTo) {
    if(LittleFS.exists(_pathFrom)) {
        LittleFS.rename(_pathFrom, _pathTo);
        snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_ren, _pathFrom.c_str(), _pathTo.c_str());
        sendLog(logBuf);
        return true;
    }
    else {
        snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_error_notFound, _pathFrom.c_str());
        sendLog(logBuf);
        return false;
    }
}



// code snippet from https://tttapa.github.io/ESP8266/Chap12%20-%20Uploading%20to%20Server.html
File fsUploadFile;              // a File object to temporarily store the received file
void FS_handleFileUpload(){ // upload a new file to the FS
  HTTPUpload& _upload = httpServer.upload();
  
  if(_upload.status == UPLOAD_FILE_START) {
    String _filename = _upload.filename;
    if(!_filename.startsWith("/")) _filename = "/"+_filename;
    fsUploadFile = LittleFS.open(_filename, "w");            // Open the file for writing in SPIFFS (create if it doesn't exist)
    snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_uploadStarted, _filename.c_str());
    sendLog(logBuf);
    _filename = String();
  } 
  else if(_upload.status == UPLOAD_FILE_WRITE) {
    if(fsUploadFile)
      fsUploadFile.write(_upload.buf, _upload.currentSize); // Write the received bytes to the file
  } 
  else if(_upload.status == UPLOAD_FILE_END ){
    if(fsUploadFile) {                                    // If the file was successfully created
      fsUploadFile.close();                               // Close the file again
      
      snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_uploadFinished, _upload.totalSize);
      sendLog(logBuf);

      //char _returnPage[31];
      //if (httpServer.hasArg("rt")) {
      //  httpServer.arg("rt").toCharArray(_returnPage, 30);
      //}
      //else {
      //  strcpy(_returnPage, "/avr");
      //}
      //httpServer.sendHeader("Location", _returnPage);      // Redirect the client to the success page

      httpServer.sendHeader("Location", httpServer_returnPage);      // Redirect the client to the success page
      
      httpServer.send(303);
    } 
    else {
      snprintf_P(logBuf, LOG_BUFFER_SIZE, PGMStr_filesystem_uploadFailed, _upload.totalSize);
      sendLog(logBuf);
      httpServer.send(500, "text/plain", "500: couldn't create file");
    }
  }
}

//void handleFileUpload_avr(){ // upload a new file to the FS
//  HTTPUpload& _upload = httpServer.upload();
//  
//  if(_upload.status == UPLOAD_FILE_START) {
//    String _filename = _upload.filename;
//    if(!_filename.startsWith("/")) _filename = "/avr/"+_filename;
//    fsUploadFile = LittleFS.open(_filename, "w");            // Open the file for writing in SPIFFS (create if it doesn't exist)
//    snprintf(logBuf, LOG_BUFFER_SIZE, "handleFileUpload - name: %s", _filename.c_str());
//    sendLog(logBuf);
//    _filename = String();
//  } 
//  else if(_upload.status == UPLOAD_FILE_WRITE) {
//    if(fsUploadFile)
//      fsUploadFile.write(_upload.buf, _upload.currentSize); // Write the received bytes to the file
//  } 
//  else if(_upload.status == UPLOAD_FILE_END ){
//    if(fsUploadFile) {                                    // If the file was successfully created
//      fsUploadFile.close();                               // Close the file again
//      
//      snprintf(logBuf, LOG_BUFFER_SIZE, "handleFileUpload - size: %d", _upload.totalSize);
//      sendLog(logBuf);
//
//      //char _returnPage[31];
//      //if (httpServer.hasArg("rt")) {
//      //  httpServer.arg("rt").toCharArray(_returnPage, 30);
//      //}
//      //else {
//      //  strcpy(_returnPage, "/avr");
//      //}
//      //httpServer.sendHeader("Location", _returnPage);      // Redirect the client to the success page
//
//      httpServer.sendHeader("Location", httpServer_returnPage);      // Redirect the client to the success page
//      
//      httpServer.send(303);
//    } 
//    else {
//      httpServer.send(500, "text/plain", "500: couldn't create file");
//    }
//  }
//}

void FS_getInfo() {
  LittleFS.info(fs_info);
}
