#include "Path.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

std::string Path::dirname(const std::string & s)
{
    size_t pos = s.find_last_of("/\\");
    if (pos == std::string::npos)
    {
        return ".";
    }
    if ((pos == 0u) || (pos == 2u && s[1] == ':'))
    {
        return std::string(s, 0, pos + 1u);
    }
    return std::string(s, 0, pos);
}

std::string Path::_join(const std::string & first, const std::string & second)
{
    if (first == "")
    {
        return second;
    }
    if (second == "")
    {
        return first;
    }
    char last = first[first.size() - 1u];
    if ((last == '/') || (last == '\\'))
    {
        return first + second;
    }
    return first + "/" + second;
}

bool Path::is_file(const std::string & s)
{
    struct stat st;
    if (stat(s.c_str(), &st) != 0)
    {
        return false;
    }
    return S_ISREG(st.st_mode);
}

bool Path::is_dir(const std::string & s)
{
    struct stat st;
    if (stat(s.c_str(), &st) != 0)
    {
        return false;
    }
    return S_ISDIR(st.st_mode);
}

std::shared_ptr<std::vector<std::shared_ptr<std::string>>> Path::listdir(const std::string & path)
{
    std::shared_ptr<std::vector<std::shared_ptr<std::string>>> result = std::make_shared<std::vector<std::shared_ptr<std::string>>>();

    DIR * dir = opendir(path.c_str());
    if (dir != nullptr)
    {
        struct dirent * ent;
        while ((ent = readdir(dir)) != nullptr)
        {
            result->push_back(std::make_shared<std::string>(ent->d_name));
        }
        closedir(dir);
    }

    return result;
}
