#include "Runtime.h"
#include "Path.h"

static const std::initializer_list<const char *> Font_Extensions = {"", ".ttf", ".otf"};
static const std::initializer_list<const char *> Shader_Extensions = {"", ".glsl"};

static std::string System_Runtime_Dir;

void Runtime::init(const char * executable_path, const char * appname)
{
    System_Runtime_Dir = Path::join(Path::dirname(Path::dirname(executable_path)), "share", appname);
}

std::string Runtime::find(Type t, const std::string & name)
{
    if (Path::is_file(name))
    {
        return name;
    }

    switch (t)
    {
    case FONT:
        return find_first_under("fonts", name, Font_Extensions, true);

    case SHADER:
        return find_first_under("shaders", name, Shader_Extensions);
    }

    return "";
}

std::string Runtime::find_first_under(const std::string & runtime_subpath,
                                      const std::string & name,
                                      const std::initializer_list<const char *> & extensions,
                                      bool look_in_subdirs)
{
    std::string system_runtime_path = Path::join(System_Runtime_Dir, runtime_subpath);
    std::string first = find_first_in(system_runtime_path, name, extensions);
    if (first.empty() && look_in_subdirs)
    {
        auto dir_ents = Path::listdir(system_runtime_path);
        for (auto dir_ent : *dir_ents)
        {
            if ((*dir_ent)[0] != '.')
            {
                std::string subpath = Path::join(system_runtime_path, *dir_ent);
                if (Path::is_dir(subpath))
                {
                    std::string p = find_first_in(subpath, name, extensions);
                    if (!p.empty())
                    {
                        return p;
                    }
                }
            }
        }
    }
    return first;
}

std::string Runtime::find_first_in(const std::string & path,
                                   const std::string & name,
                                   const std::initializer_list<const char *> & extensions)
{
    for (auto ext : extensions)
    {
        std::string attempt_path = Path::join(path, name + ext);
        if (Path::is_file(attempt_path))
        {
            return attempt_path;
        }
    }

    return "";
}
