/*****
* locate.cc
* Tom Prince 2005/03/24
*
* Locate files in search path.
*****/

#include "settings.h"
#include "util.h"
#include "locate.h"


namespace settings {

namespace fs {

string extension(string name)
{
 size_t n = name.rfind(".");
 if (n != string::npos)
   return name.substr(n);
 else
   return string();
}

bool exists(string filename)
{
 return fileExists(filename);
}

} // namespace fs


file_list_t searchPath;

// Returns list of possible filenames, accounting for extensions.
file_list_t mungeFileName(string id, string suffix)
{
 string ext = fs::extension(id);
 file_list_t files;
 if (ext == "."+suffix) {
   files.push_back(id);
   files.push_back(id+"."+suffix);
 } else {
   files.push_back(id+"."+suffix);
   files.push_back(id);
 }
 return files;
}

// Join a directory with the given filename, to give the path to the file,
// avoiding unsightly joins such as 'dir//file.asy' in favour of 'dir/file.asy'
string join(string dir, string file, bool full)
{
 return dir == "." ? (full ? string(getPath())+"/"+file : file) :
   *dir.rbegin() == '/' ? dir + file :
   dir + "/" + file;
}

// Find the appropriate file, first looking in the local directory, then the
// directory given in settings, and finally the global system directory.
string locateFile(string id, bool full, string suffix)
{
 if(id.empty()) return "";
 file_list_t filenames = mungeFileName(id,suffix);
 for (auto const& leaf : filenames) {
   if (leaf[0] == '/') { // FIXME: Add windows path check
     string file = leaf;
     if (fs::exists(file))
       return file;
   } else {
     for (auto const& dir : searchPath) {
       string file = join(dir,leaf,full);
       if (fs::exists(file))
         return file;
     }
   }
 }
 return string();
}

} // namespace settings