#include "SD.h"
#include "SPI.h"

#define HSPI_MISO   12
#define HSPI_MOSI   13
#define HSPI_SCLK   14
#define HSPI_SS     27

SPIClass * hspi = NULL;
static const uint32_t hspiClk = 16000000; // 16 MHz  The sd card im using only supports 8 or 16 Mhz spi.

bool  StorageMounted = false;
void setup(){ 
 
   Serial.begin(115200);
    hspi = new SPIClass(HSPI);
    hspi->begin(HSPI_SCLK,HSPI_MISO,HSPI_MOSI,HSPI_SS);
    bool SD_OK =  SD.begin(HSPI_SS,*(hspi));
   
    if(!SD_OK){
      StorageMounted = false;
        Serial.println("Card Mount Failed");
        return;
    }
    else {  StorageMounted = true ; Serial.println("Card Mounted. "); }
    
     uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);

    listDir(SD, "/", 0);
}


void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void readFile(fs::FS &fs, const char * path, char* FileBuffer, uint32_t FileSize){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");

    while(file.available()){
        file.readBytes(FileBuffer, FileSize);
    }
    file.close();
}


bool disableREAD =false;
char* DBuffer = (char*)malloc(1024);

void loop(){
 
   if(StorageMounted && !disableREAD)
  {
     readFile(SD, "/sketch.ino",DBuffer,8);
     Serial.println("Done Reading");
     disableREAD =true;
  }
}