#pragma once

#include "Dtypes.h"

#ifdef PLATFORM_ESP32
#include "SPIFFS.h"

namespace portablefs
{
    using File = ::File;

    class Dir
    {
    public:
        Dir() {}
        Dir(const String &path)
            : root_(SPIFFS.open(path))
        {
            //next();
        }

        bool next()
        {
            file_ = root_.openNextFile();
            return file_;
        }

        bool isFile()
        {
            return !file_.isDirectory();
        }

        bool isDirectory()
        {
            return file_.isDirectory();
        }

        String fileName() const
        {
            return file_.name();
        }

        size_t fileSize() const
        {
            return file_.size();
        }

    private:
        File root_;
        File file_;
    };

    inline Dir openDir(const String &path)
    {
        return Dir(path);
    }

    inline File open(const char *name, const char *mode)
    {
        return SPIFFS.open(name, mode);
    }

    inline bool exists(const char *name)
    {
        return SPIFFS.exists(name);
    }

    inline bool remove(const char *name)
    {
        return SPIFFS.remove(name);
    }

    inline bool mkdir(const char *name)
    {
        return SPIFFS.mkdir(name);
    }
    
    inline size_t usedBytes() 
    {
        return SPIFFS.usedBytes();
    }

    inline size_t totalBytes()
    {
        return SPIFFS.totalBytes();
    }

} // namespace portablefs

#endif

#ifdef PLATFORM_ESP8266

#include <FS.h>

namespace portablefs
{
    using Dir;
} // namespace portablefs

#endif

#ifdef PLATFORM_NATIVE

#include <string>
#include <fstream>
#include <filesystem>

namespace fs = std::filesystem;


namespace portablefs
{
    const std::string basePath = "./base";
    
    class Dir
    {
    public:
        Dir() {}
        Dir(const String &path)
            : it_(fs::directory_iterator(path).begin()),
              end_(fs::directory_iterator(path).end()),
              firstIncremented_(false)
        {
        }

        bool next()
        {
            if (!firstIncremented_)
                firstIncremented_ = true;
            else
                ++it_;

            return it_ != end_;
        }

        bool isFile()
        {
            return file.is_regular_file();
        }

        bool isDirectory()
        {
            return it_.is_directory();
        }

        String fileName() const
        {
            return it_.path().filename().string();
        }

        size_t fileSize() const
        {
            return it_.file_size();
        }

    private:
        fs::directory_iterator it_;
        fs::directory_iterator end_;
        bool firstIncremented_;
    };

    inline Dir openDir(const String &path)
    {
        return Dir(path);
    }

    inline File open(const char *name, const char *mode)
    {
        if(mode == "r")
            return fopen()
        return SPIFFS.open(name, mode);
    }

    inline bool exists(const char *name)
    {
        return SPIFFS.exists(name);
    }

    inline bool remove(const char *name)
    {
        return SPIFFS.remove(name);
    }

    inline bool mkdir(const char *name)
    {
        return SPIFFS.mkdir(name);
    }    

} // namespace portablefs

#endif