#include "serilaFS.h"
#include <Arduino.h>
#include "SDmanger.h"
#include <Define.h>
#include "mymsc.h"
Stream *Serilaforfs = nullptr;
bool ListDir(const char *dirname)
{
  String dir(dirname);
  File root = SD_MMC.open(dirname);
  if (!root)
  {
    Serial.println("Failed to open directory");
    return true;
  }
  if (!root.isDirectory())
  {
    Serial.println("Not a directory");
    return true;
  }
  Serilaforfs->println("------------------------------------ " + dir + "------------------------------------");
  if (dir == "/")
  {
    dir = "";
    /* code */
  }

  File filex = root.openNextFile();
  int i = 0;
  while (filex)
  {
    if (filex.isDirectory())
    {

      Serial.println(dir + "/" + String(filex.name()));
    }
    else
    {

      Serial.println(dir + "/" + String(filex.name()) + "\t Size:" + String(filex.size() / 1024) + " Kb");
    }
    vTaskDelay(1);
    Serial.flush();
    filex = root.openNextFile();
    i++;
    if (i % 20 == 0)
    {
      vTaskDelay(1);
    };
  }

  return true;
}

void deleteFolderOrFile(const char *val)
{
  // Function provided by user @gemi254
  Serial.printf("Deleting : %s\n", val);
  File f = SD_MMC.open(val);
  if (!f)
  {
    Serial.printf("Failed to open %s\n", val);
    return;
  }

  if (f.isDirectory())
  {
    File file = f.openNextFile();
    while (file)
    {
      if (file.isDirectory())
      {
        Serial.print("  DIR : ");
        Serial.println(file.name());
      }
      else
      {
        Serial.print("  FILE: ");
        Serial.print(file.name());
        Serial.print("  SIZE: ");
        Serial.print(file.size());
        if (SD_MMC.remove(file.name()))
        {
          Serial.println(" deleted.");
        }
        else
        {
          Serial.println(" FAILED.");
        }
      }
      file = f.openNextFile();
    }
    f.close();
    // Remove the dir
    if (SD_MMC.rmdir(val))
    {
      Serial.printf("Dir %s removed\n", val);
    }
    else
    {
      Serial.println("Remove dir failed");
    }
  }
  else
  {
    // Remove the file
    if (SD_MMC.remove(val))
    {
      Serial.printf("File %s deleted\n", val);
    }
    else
    {
      Serial.println("Delete failed");
    }
  }
}

void GetFile(const char *filepath)
{
  String path(filepath);
  File file = SD_MMC.open(filepath, "rb");
  if (!file || file.isDirectory())
  {
    Serial.println("Error: File not found or is a directory");
    return;
  }
  Serial.println("File Size: " + String(file.size() / 1024) + " Kb");
  const size_t bufferSize = 512;
  uint8_t buffer[bufferSize];
  size_t bytesRead;
  while ((bytesRead = file.read(buffer, bufferSize)) > 0)
  {
    Serilaforfs->write(buffer, bytesRead);
    // 延时一下防止阻塞
    vTaskDelay(1);
  }
  file.close();
  Serilaforfs->println("\n--- End of File ---");
}

void TaskSerialFS(void *pvParameters)
{
  Serilaforfs = &Serial;
  if (Serilaforfs == nullptr)
    vTaskDelete(NULL);
  ;

  while (1)
  {
    // vTaskDelay(1);
    // Serilaforfs->println("SerilaFS Task Running...");
    // Serial.printf("SerilaFS Command Recv : ");
    if (Serilaforfs->available())
    {

      // Serial.println("SerilaFS Command Recv : ");
      String command = Serilaforfs->readStringUntil('\n');
      command.trim(); // 去除命令字符串的前后空白字符
      // 命令格式 command 参数1  command 有 ls 及 get 两种 先分割 rm
      int spaceIndex = command.indexOf(' ');
      String cmd;
      String param;
      if (spaceIndex != -1)
      {
        cmd = command.substring(0, spaceIndex);
        param = command.substring(spaceIndex + 1);
      }
      else
      {
        cmd = command; // 如果没有参数，整个字符串就是命令
        param = "/";
      }
      // 如果param不是./开头 返回错误
      if (!param.startsWith("/"))
      {
        Serilaforfs->println("Error: Path must start with ./");
        vTaskDelay(1);
        continue;
        ;
      }
      if (cmd == "ls")
      {

        sdcard::lock();
        ListDir(param.c_str());
        sdcard::unlock();
      }
      if (cmd == "get")
      {
        sdcard::lock();
        GetFile(param.c_str());
        sdcard::unlock();
        Serilaforfs->println("\n--- End of File ---");
      }
      if (cmd == "rm")
      {
        sdcard::lock();
        if (SD_MMC.remove(param.c_str()))
        {
          Serilaforfs->printf("File %s deleted\n", param.c_str());
        }
        else
        {
          Serilaforfs->println("Delete failed");
        }
        sdcard::unlock();
      }
      if (cmd == "rmdir")
      {
        sdcard::lock();
        if (SD_MMC.rmdir(param.c_str()))
        {
          Serilaforfs->printf("Dir %s deleted\n", param.c_str());
        }
        else
        {
          Serilaforfs->println("Remove dir failed");
        }
        sdcard::unlock();
      }
      if (cmd == "rmdirfiles")
      {
        sdcard::lock();
        sdcard::deleteFolderOrFile(param.c_str());
        sdcard::unlock();
      }
      if (cmd == "msc")
      {
        Serilaforfs->println("start msc wait for mount sdcard");
        xEventGroupSetBits(Eventgroup, START_MSC_BIT);
      }

      if (cmd == "stop")
      {
        Serilaforfs->println("waiting for stop work");
        xEventGroupSetBits(Eventgroup, STOP_WORK_BIT);
      }
      if (cmd == "start")
      {
        xEventGroupSetBits(Eventgroup, StART_WORK_BIT);
      }
      if (cmd == "format")
      {
        String passwd=param;
        if(passwd!="/iris")
        {
          Serilaforfs->println("Error: Wrong password for format sdcard");
          vTaskDelay(1);
          continue;
        }
        Serilaforfs->println("Start format sdcard");
        sdcard::lock();
        sdcard::formatSDCard();
        sdcard::unlock();
        Serilaforfs->println("Format sdcard completed");
        //重启
        ESP.restart();
      }
      if (cmd == "help" || cmd == "?" || cmd == "h")
      {
        Serilaforfs->println("Command List:");
        Serilaforfs->println("ls <path> - List files in directory");
        Serilaforfs->println("get <path> - Get file content");
        Serilaforfs->println("rm <path> - Remove file");
        Serilaforfs->println("rmdir <path> - Remove directory");
        Serilaforfs->println("rmdirfiles <path> - Remove directory and all its contents");
        Serilaforfs->println("msc - Start Mass Storage Class (MSC) mode");
        Serilaforfs->println("format <password> - Format the SD card (password required)");
        Serilaforfs->println("help - Show this help message");
        Serilaforfs->println("stop - Stop system work");
        Serilaforfs->println("start - Start system work");
      }

      /* code */
    }

    vTaskDelay(1);
    /* code */
  }

  Serial.println("TaskSerialFS exit");
  vTaskDelay(1);
  vTaskDelete(NULL);
}
