#include <Arduino.h>
//#include <ESP32Time.h>

//ESP32Time rtc;

#define _DEBUG_


#include <SPI.h>

SPIClass SD_SPI = SPIClass(HSPI);

#include <SD.h>
//#include <FS.h>

File trkFile;

#include "defs.h"

//------------------------------------------------------------------------------
void printDirectory(File dir, int numTabs) {
  while (true) {
    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      fileCount++;
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}
//------------------------------------------------------------------------------

void setup() {
  pinMode(SD_LED, OUTPUT);
  digitalWrite(SD_LED, LOW);

  fileName.reserve(30);
  Serial.begin(115200);
  Serial.println("\r\n\r\n");
  //  Serial.printf(frmt,123);
  delay(5000);


  validSDcard = SD.begin(SD_CS, SD_SPI);
  digitalWrite(SD_LED, validSDcard ? HIGH : LOW);
  Serial.print("SD Valida: ");
  Serial.println(validSDcard ? "SI\r\n" : "NO\r\n");
  fileName = "/Archive";
  if (validSDcard) {
    if (!SD.exists(fileName)) {
      SD.mkdir("/Archive");  // crear directorio
      Serial.print("Carpeta ");
      Serial.print(fileName);
      Serial.print(" creada: ");
      Serial.println(SD.exists(fileName) ? "SI\r\n" : "NO\r\n");
      trkFile.close();
    } else {
      Serial.printf("Carpeta %s ya existe\r\n", fileName);
    }
/*
    trkFile = SD.open("/Archive/001.gpx", FILE_WRITE);
    trkFile.close();
    trkFile = SD.open("/Archive/002.gpx", FILE_WRITE);
    trkFile.close();
    trkFile = SD.open("/Archive/003.gpx", FILE_WRITE);
    trkFile.close();
    trkFile = SD.open("/Archive/004.gpx", FILE_WRITE);
    trkFile.close();
    trkFile = SD.open("/Archive/005.gpx", FILE_WRITE);
    trkFile.close();
*/
    trkFile = SD.open("/Archive");
    fileCount = 0;
    printDirectory(trkFile, 0);
    trkFile.close();
    fileName = "/Archive/005.gpx";
    if (SD.exists(fileName)) {
      SD.remove(fileName);
      Serial.println(fileName + " eliminado.");
    }
    else {
      Serial.println(fileName + " no existe.");
    }

    //  SD.remove("/Archive/004.gpx");
    //  SD.remove("/Archive/003.gpx");
    //  SD.remove("/Archive/002.gpx");
    //  SD.remove("/Archive/001.gpx");
    trkFile = SD.open("/Archive");
    fileCount = 0;
    printDirectory(trkFile, 0);
    trkFile.close();
    //  SD.rmdir("/Archive");


    fileName = "/current.gpx";
    trkFile = SD.open(fileName, FILE_WRITE);
    Serial.printf("%s creado: ", fileName);
    Serial.println(SD.exists(fileName) ? "SI\r\n" : "NO\r\n");
    delay(500);

    char stime[21];  //2023-04-03T02:45:23Z";
    sprintf(stime, gpx_timefmt /*"%04d-%02d-%02dT%02d:%02d:%02dZ"*/, year, month, day, hour, minute, second);

    if (trkFile) {
      digitalWrite(SD_LED, LOW);
      delay(250);
      trkFile.print(gpx_header);
      trkFile.printf(gpx_trkname, year, month, day - 1, (hour - 3 + 24) % 24, minute, second); // localtime mediopelo
      trkFile.printf(gpx_trkpt, lat, lng, ele, stime, cur, spd, sats);
      trkFile.print(gpx_end); // </gpx>
      digitalWrite(SD_LED, HIGH);

      trkFile.close();
    }
    trkFile = SD.open(fileName, FILE_READ);
    if (trkFile) {
      Serial.printf("File len: %d\r\n", trkFile.size());

      Serial.println("Read from file: ");
      while (trkFile.available()) {
        Serial.write(trkFile.read());
      }
      trkFile.close();
    }
    delay(2000);

    int seekPos;
    trkFile = SD.open(fileName, FILE_READ);
    if (trkFile) {
      Serial.printf("File len: %d\r\n", trkFile.size());
      trkFile.seek(trkFile.size() - 20);
      Serial.println("Read from file 1: ");
      String chrGpx = "";
      while (trkFile.available()) {
        char dato = trkFile.read();
        chrGpx += dato;
        Serial.write(dato);
      }
      trkFile.close();
      int pos = chrGpx.lastIndexOf("</gpx>");
      if (pos >= 0) {
        seekPos = chrGpx.length() - pos;
        validGpx = true;
      }
      Serial.println("pos= " + String(seekPos));
      if (validGpx) {
        Serial.println("GPX valido");
      }
      delay(3000);
    }
    delay(1000);
    trkFile = SD.open(fileName, FILE_WRITE);
    sprintf(stime, gpx_timefmt /*"%04d-%02d-%02dT%02d:%02d:%02dZ"*/, year, month, day, hour, minute, second + 1);
    if (trkFile) {
      Serial.printf("File len: %d\r\n", trkFile.size());
      trkFile.seek(trkFile.size() - seekPos);
      digitalWrite(SD_LED, LOW);
      delay(250);
      trkFile.printf(gpx_trkpt, lat, lng, ele, stime, cur, spd, sats);
      trkFile.print(gpx_trkend);
      trkFile.print(gpx_end);
      digitalWrite(SD_LED, HIGH);
      //      trkFile.println("</gpx>");
      trkFile.close();
    }
  //  trkFile = SD.open(fileName, FILE_READ);
    //  String file2 = "/Archive/current_copia.gpx";
    char file2[40];
    sprintf(file2, "/Archive/%03d.gpx", fileCount + 1);
    trkFile = SD.open(fileName, FILE_READ);
    if (trkFile) {
      Serial.printf("File len: %d\r\n", trkFile.size());
      Serial.println("Read from file: ");
      while (trkFile.available()) {
        char dato = trkFile.read();
        Serial.write(dato);
      }
      trkFile.close();
    }
/*    if (SD.exists(file2)) {
      Serial.println("Arch " + String(file2) + " creado");
      delay(3000);
    }
    copia = SD.open(file2, FILE_READ);
    if (copia) {
      Serial.printf("File len: %d\r\n", copia.size());
      Serial.println("Read from file 3: ");
      while (copia.available()) {
        char dato = copia.read();
        Serial.write(dato);
      }
      copia.close();
    }
*/
//    char f1[] = "/Archive/001.gpx";
//    char f2[] = "/Archive/111.gpx";
    
    if (SD.rename(fileName,file2)) {
      Serial.println("File renamed");
    } else {
      Serial.println("Rename failed");
    }
    delay(5000);
    trkFile = SD.open("/");
    printDirectory(trkFile, 0);
  }
  digitalWrite(SD_LED, LOW);
  Serial.println("Terminado!");
}

void loop() {
  delay(1);
}

//------------------------------------------------------------------------------