//===- llvm/System/Linux/Path.cpp - Linux Path Implementation ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// Modified by Henrik Bach to comply with at least MinGW.
// Ported to Win32 by Jeff Cohen.
//
//===----------------------------------------------------------------------===//
//
// This file provides the Win32 specific implementation of the Path class.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic Win32 code that
//===          is guaranteed to work on *all* Win32 variants.
//===----------------------------------------------------------------------===//

#include "Win32.h"
#include <malloc.h>

// We need to undo a macro defined in Windows.h, otherwise we won't compile:
#undef CopyFile
#undef GetCurrentDirectory

// Windows happily accepts either forward or backward slashes, though any path
// returned by a Win32 API will have backward slashes.  As LLVM code basically
// assumes forward slashes are used, backward slashs are converted where they
// can be introduced into a path.
//
// Another invariant is that a path ends with a slash if and only if the path
// is a root directory.  Any other use of a trailing slash is stripped.  Unlike
// in Unix, Windows has a rather complicated notion of a root path and this
// invariant helps simply the code.

static void FlipBackSlashes(std::string& s) {
  for (size_t i = 0; i < s.size(); i++)
    if (s[i] == '\\')
      s[i] = '/';
}

namespace llvm {
namespace sys {
const char PathSeparator = ';';

bool
Path::isValid() const {
  if (path.empty())
    return false;

  // If there is a colon, it must be the second character, preceded by a letter
  // and followed by something.
  size_t len = path.size();
  size_t pos = path.rfind(':',len);
  size_t rootslash = 0;
  if (pos != std::string::npos) {
    if (pos != 1 || !isalpha(path[0]) || len < 3)
      return false;
      rootslash = 2;
  }

  // Look for a UNC path, and if found adjust our notion of the root slash.
  if (len > 3 && path[0] == '/' && path[1] == '/') {
    rootslash = path.find('/', 2);
    if (rootslash == std::string::npos)
      rootslash = 0;
  }

  // Check for illegal characters.
  if (path.find_first_of("\\<>\"|\001\002\003\004\005\006\007\010\011\012"
                         "\013\014\015\016\017\020\021\022\023\024\025\026"
                         "\027\030\031\032\033\034\035\036\037")
      != std::string::npos)
    return false;

  // Remove trailing slash, unless it's a root slash.
  if (len > rootslash+1 && path[len-1] == '/')
    path.erase(--len);

  // Check each component for legality.
  for (pos = 0; pos < len; ++pos) {
    // A component may not end in a space.
    if (path[pos] == ' ') {
      if (path[pos+1] == '/' || path[pos+1] == '\0')
        return false;
    }

    // A component may not end in a period.
    if (path[pos] == '.') {
      if (path[pos+1] == '/' || path[pos+1] == '\0') {
        // Unless it is the pseudo-directory "."...
        if (pos == 0 || path[pos-1] == '/' || path[pos-1] == ':')
          return true;
        // or "..".
        if (pos > 0 && path[pos-1] == '.') {
          if (pos == 1 || path[pos-2] == '/' || path[pos-2] == ':')
            return true;
        }
        return false;
      }
    }
  }

  return true;
}

bool 
Path::isAbsolute() const {
  switch (path.length()) {
    case 0:
      return false;
    case 1:
    case 2:
      return path[0] == '/';
    default:
      return path[0] == '/' || (path[1] == ':' && path[2] == '/');
  }
} 

static Path *TempDirectory = NULL;

Path
Path::GetTemporaryDirectory(std::string* ErrMsg) {
  if (TempDirectory)
    return *TempDirectory;

  char pathname[MAX_PATH];
  if (!GetTempPath(MAX_PATH, pathname)) {
    if (ErrMsg)
      *ErrMsg = "Can't determine temporary directory";
    return Path();
  }

  Path result;
  result.set(pathname);

  // Append a subdirectory passed on our process id so multiple LLVMs don't
  // step on each other's toes.
#ifdef __MINGW32__
  // Mingw's Win32 header files are broken.
  sprintf(pathname, "LLVM_%u", unsigned(GetCurrentProcessId()));
#else
  sprintf(pathname, "LLVM_%u", GetCurrentProcessId());
#endif
  result.appendComponent(pathname);

  // If there's a directory left over from a previous LLVM execution that
  // happened to have the same process id, get rid of it.
  result.eraseFromDisk(true);

  // And finally (re-)create the empty directory.
  result.createDirectoryOnDisk(false);
  TempDirectory = new Path(result);
  return *TempDirectory;
}

// FIXME: the following set of functions don't map to Windows very well.
Path
Path::GetRootDirectory() {
  Path result;
  result.set("C:/");
  return result;
}

void
Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
  Paths.push_back(sys::Path("C:/WINDOWS/SYSTEM32"));
  Paths.push_back(sys::Path("C:/WINDOWS"));
}

void
Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
  char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
  if (env_var != 0) {
    getPathList(env_var,Paths);
  }
#ifdef LLVM_LIBDIR
  {
    Path tmpPath;
    if (tmpPath.set(LLVM_LIBDIR))
      if (tmpPath.canRead())
        Paths.push_back(tmpPath);
  }
#endif
  GetSystemLibraryPaths(Paths);
}

Path
Path::GetLLVMDefaultConfigDir() {
  // TODO: this isn't going to fly on Windows
  return Path("/etc/llvm");
}

Path
Path::GetUserHomeDirectory() {
  // TODO: Typical Windows setup doesn't define HOME.
  const char* home = getenv("HOME");
  if (home) {
    Path result;
    if (result.set(home))
      return result;
  }
  return GetRootDirectory();
}

Path
Path::GetCurrentDirectory() {
  char pathname[MAX_PATH];
  ::GetCurrentDirectoryA(MAX_PATH,pathname);
  return Path(pathname);  
}

/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
  return Path();
}


// FIXME: the above set of functions don't map to Windows very well.


bool
Path::isRootDirectory() const {
  size_t len = path.size();
  return len > 0 && path[len-1] == '/';
}

std::string Path::getDirname() const {
  return getDirnameCharSep(path, '\\');
}

std::string
Path::getBasename() const {
  // Find the last slash
  size_t slash = path.rfind('/');
  if (slash == std::string::npos)
    slash = 0;
  else
    slash++;

  size_t dot = path.rfind('.');
  if (dot == std::string::npos || dot < slash)
    return path.substr(slash);
  else
    return path.substr(slash, dot - slash);
}

bool
Path::exists() const {
  DWORD attr = GetFileAttributes(path.c_str());
  return attr != INVALID_FILE_ATTRIBUTES;
}

bool
Path::isDirectory() const {
  DWORD attr = GetFileAttributes(path.c_str());
  return (attr != INVALID_FILE_ATTRIBUTES) &&
         (attr & FILE_ATTRIBUTE_DIRECTORY);
}

bool
Path::canRead() const {
  // FIXME: take security attributes into account.
  DWORD attr = GetFileAttributes(path.c_str());
  return attr != INVALID_FILE_ATTRIBUTES;
}

bool
Path::canWrite() const {
  // FIXME: take security attributes into account.
  DWORD attr = GetFileAttributes(path.c_str());
  return (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_READONLY);
}

bool
Path::canExecute() const {
  // FIXME: take security attributes into account.
  DWORD attr = GetFileAttributes(path.c_str());
  return attr != INVALID_FILE_ATTRIBUTES;
}

std::string
Path::getLast() const {
  // Find the last slash
  size_t pos = path.rfind('/');

  // Handle the corner cases
  if (pos == std::string::npos)
    return path;

  // If the last character is a slash, we have a root directory
  if (pos == path.length()-1)
    return path;

  // Return everything after the last slash
  return path.substr(pos+1);
}

const FileStatus *
PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
  if (!fsIsValid || update) {
    WIN32_FILE_ATTRIBUTE_DATA fi;
    if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
      MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
                      ": Can't get status: ");
      return 0;
    }

    status.fileSize = fi.nFileSizeHigh;
    status.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
    status.fileSize += fi.nFileSizeLow;

    status.mode = fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0555 : 0777;
    status.user = 9999;    // Not applicable to Windows, so...
    status.group = 9999;   // Not applicable to Windows, so...

    // FIXME: this is only unique if the file is accessed by the same file path.
    // How do we do this for C:\dir\file and ..\dir\file ? Unix has inode
    // numbers, but the concept doesn't exist in Windows.
    status.uniqueID = 0;
    for (unsigned i = 0; i < path.length(); ++i)
      status.uniqueID += path[i];

    __int64 ft = *reinterpret_cast<__int64*>(&fi.ftLastWriteTime);
    status.modTime.fromWin32Time(ft);

    status.isDir = fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
    fsIsValid = true;
  }
  return &status;
}

bool Path::makeReadableOnDisk(std::string* ErrMsg) {
  // All files are readable on Windows (ignoring security attributes).
  return false;
}

bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
  DWORD attr = GetFileAttributes(path.c_str());

  // If it doesn't exist, we're done.
  if (attr == INVALID_FILE_ATTRIBUTES)
    return false;

  if (attr & FILE_ATTRIBUTE_READONLY) {
    if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) {
      MakeErrMsg(ErrMsg, std::string(path) + ": Can't make file writable: ");
      return true;
    }
  }
  return false;
}

bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
  // All files are executable on Windows (ignoring security attributes).
  return false;
}

bool
Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
  WIN32_FILE_ATTRIBUTE_DATA fi;
  if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) {
    MakeErrMsg(ErrMsg, path + ": can't get status of file");
    return true;
  }
    
  if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
    if (ErrMsg)
      *ErrMsg = path + ": not a directory";
    return true;
  }

  result.clear();
  WIN32_FIND_DATA fd;
  std::string searchpath = path;
  if (path.size() == 0 || searchpath[path.size()-1] == '/')
    searchpath += "*";
  else
    searchpath += "/*";

  HANDLE h = FindFirstFile(searchpath.c_str(), &fd);
  if (h == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
      return true; // not really an error, now is it?
    MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
    return true;
  }

  do {
    if (fd.cFileName[0] == '.')
      continue;
    Path aPath(path);
    aPath.appendComponent(&fd.cFileName[0]);
    result.insert(aPath);
  } while (FindNextFile(h, &fd));

  DWORD err = GetLastError();
  FindClose(h);
  if (err != ERROR_NO_MORE_FILES) {
    SetLastError(err);
    MakeErrMsg(ErrMsg, path + ": Can't read directory: ");
    return true;
  }
  return false;
}

bool
Path::set(const std::string& a_path) {
  if (a_path.empty())
    return false;
  std::string save(path);
  path = a_path;
  FlipBackSlashes(path);
  if (!isValid()) {
    path = save;
    return false;
  }
  return true;
}

bool
Path::appendComponent(const std::string& name) {
  if (name.empty())
    return false;
  std::string save(path);
  if (!path.empty()) {
    size_t last = path.size() - 1;
    if (path[last] != '/')
      path += '/';
  }
  path += name;
  if (!isValid()) {
    path = save;
    return false;
  }
  return true;
}

bool
Path::eraseComponent() {
  size_t slashpos = path.rfind('/',path.size());
  if (slashpos == path.size() - 1 || slashpos == std::string::npos)
    return false;
  std::string save(path);
  path.erase(slashpos);
  if (!isValid()) {
    path = save;
    return false;
  }
  return true;
}

bool
Path::appendSuffix(const std::string& suffix) {
  std::string save(path);
  path.append(".");
  path.append(suffix);
  if (!isValid()) {
    path = save;
    return false;
  }
  return true;
}

bool
Path::eraseSuffix() {
  size_t dotpos = path.rfind('.',path.size());
  size_t slashpos = path.rfind('/',path.size());
  if (dotpos != std::string::npos) {
    if (slashpos == std::string::npos || dotpos > slashpos+1) {
      std::string save(path);
      path.erase(dotpos, path.size()-dotpos);
      if (!isValid()) {
        path = save;
        return false;
      }
      return true;
    }
  }
  return false;
}

inline bool PathMsg(std::string* ErrMsg, const char* pathname, const char*msg) {
  if (ErrMsg)
    *ErrMsg = std::string(pathname) + ": " + std::string(msg);
  return true;
}

bool
Path::createDirectoryOnDisk(bool create_parents, std::string* ErrMsg) {
  // Get a writeable copy of the path name
  size_t len = path.length();
  char *pathname = reinterpret_cast<char *>(_alloca(len+2));
  path.copy(pathname, len);
  pathname[len] = 0;

  // Make sure it ends with a slash.
  if (len == 0 || pathname[len - 1] != '/') {
    pathname[len] = '/';
    pathname[++len] = 0;
  }

  // Determine starting point for initial / search.
  char *next = pathname;
  if (pathname[0] == '/' && pathname[1] == '/') {
    // Skip host name.
    next = strchr(pathname+2, '/');
    if (next == NULL)
      return PathMsg(ErrMsg, pathname, "badly formed remote directory");

    // Skip share name.
    next = strchr(next+1, '/');
    if (next == NULL)
      return PathMsg(ErrMsg, pathname,"badly formed remote directory");

    next++;
    if (*next == 0)
      return PathMsg(ErrMsg, pathname, "badly formed remote directory");

  } else {
    if (pathname[1] == ':')
      next += 2;    // skip drive letter
    if (*next == '/')
      next++;       // skip root directory
  }

  // If we're supposed to create intermediate directories
  if (create_parents) {
    // Loop through the directory components until we're done
    while (*next) {
      next = strchr(next, '/');
      *next = 0;
      if (!CreateDirectory(pathname, NULL))
          return MakeErrMsg(ErrMsg, 
            std::string(pathname) + ": Can't create directory: ");
      *next++ = '/';
    }
  } else {
    // Drop trailing slash.
    pathname[len-1] = 0;
    if (!CreateDirectory(pathname, NULL)) {
      return MakeErrMsg(ErrMsg, std::string(pathname) + ": Can't create directory: ");
    }
  }
  return false;
}

bool
Path::createFileOnDisk(std::string* ErrMsg) {
  // Create the file
  HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
                        FILE_ATTRIBUTE_NORMAL, NULL);
  if (h == INVALID_HANDLE_VALUE)
    return MakeErrMsg(ErrMsg, path + ": Can't create file: ");

  CloseHandle(h);
  return false;
}

bool
Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
  WIN32_FILE_ATTRIBUTE_DATA fi;
  if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
    return true;
    
  if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    // If it doesn't exist, we're done.
    if (!exists())
      return false;

    char *pathname = reinterpret_cast<char *>(_alloca(path.length()+3));
    int lastchar = path.length() - 1 ;
    path.copy(pathname, lastchar+1);

    // Make path end with '/*'.
    if (pathname[lastchar] != '/')
      pathname[++lastchar] = '/';
    pathname[lastchar+1] = '*';
    pathname[lastchar+2] = 0;

    if (remove_contents) {
      WIN32_FIND_DATA fd;
      HANDLE h = FindFirstFile(pathname, &fd);

      // It's a bad idea to alter the contents of a directory while enumerating
      // its contents. So build a list of its contents first, then destroy them.

      if (h != INVALID_HANDLE_VALUE) {
        std::vector<Path> list;

        do {
          if (strcmp(fd.cFileName, ".") == 0)
            continue;
          if (strcmp(fd.cFileName, "..") == 0)
            continue;

          Path aPath(path);
          aPath.appendComponent(&fd.cFileName[0]);
          list.push_back(aPath);
        } while (FindNextFile(h, &fd));

        DWORD err = GetLastError();
        FindClose(h);
        if (err != ERROR_NO_MORE_FILES) {
          SetLastError(err);
          return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
        }

        for (std::vector<Path>::iterator I = list.begin(); I != list.end();
             ++I) {
          Path &aPath = *I;
          aPath.eraseFromDisk(true);
        }
      } else {
        if (GetLastError() != ERROR_FILE_NOT_FOUND)
          return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
      }
    }

    pathname[lastchar] = 0;
    if (!RemoveDirectory(pathname))
      return MakeErrMsg(ErrStr, 
        std::string(pathname) + ": Can't destroy directory: ");
    return false;
  } else {
    // Read-only files cannot be deleted on Windows.  Must remove the read-only
    // attribute first.
    if (fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
      if (!SetFileAttributes(path.c_str(),
                             fi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
        return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
    }

    if (!DeleteFile(path.c_str()))
      return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
    return false;
  }
}

bool Path::getMagicNumber(std::string& Magic, unsigned len) const {
  assert(len < 1024 && "Request for magic string too long");
  char* buf = (char*) alloca(1 + len);

  HANDLE h = CreateFile(path.c_str(),
                        GENERIC_READ,
                        FILE_SHARE_READ,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);
  if (h == INVALID_HANDLE_VALUE)
    return false;

  DWORD nRead = 0;
  BOOL ret = ReadFile(h, buf, len, &nRead, NULL);
  CloseHandle(h);

  if (!ret || nRead != len)
    return false;

  buf[len] = '\0';
  Magic = buf;
  return true;
}

bool
Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
  if (!MoveFileEx(path.c_str(), newName.c_str(), MOVEFILE_REPLACE_EXISTING))
    return MakeErrMsg(ErrMsg, "Can't move '" + path + "' to '" + newName.path 
        + "': ");
  return false;
}

bool
Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrMsg) const {
  // FIXME: should work on directories also.
  if (!si.isFile) {
    return true;
  }
  
  HANDLE h = CreateFile(path.c_str(),
                        FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                        NULL,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);
  if (h == INVALID_HANDLE_VALUE)
    return true;

  BY_HANDLE_FILE_INFORMATION bhfi;
  if (!GetFileInformationByHandle(h, &bhfi)) {
    DWORD err = GetLastError();
    CloseHandle(h);
    SetLastError(err);
    return MakeErrMsg(ErrMsg, path + ": GetFileInformationByHandle: ");
  }

  FILETIME ft;
  (uint64_t&)ft = si.modTime.toWin32Time();
  BOOL ret = SetFileTime(h, NULL, &ft, &ft);
  DWORD err = GetLastError();
  CloseHandle(h);
  if (!ret) {
    SetLastError(err);
    return MakeErrMsg(ErrMsg, path + ": SetFileTime: ");
  }

  // Best we can do with Unix permission bits is to interpret the owner
  // writable bit.
  if (si.mode & 0200) {
    if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
      if (!SetFileAttributes(path.c_str(),
              bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
        return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
    }
  } else {
    if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
      if (!SetFileAttributes(path.c_str(),
              bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY))
        return MakeErrMsg(ErrMsg, path + ": SetFileAttributes: ");
    }
  }

  return false;
}

bool
CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg) {
  // Can't use CopyFile macro defined in Windows.h because it would mess up the
  // above line.  We use the expansion it would have in a non-UNICODE build.
  if (!::CopyFileA(Src.c_str(), Dest.c_str(), false))
    return MakeErrMsg(ErrMsg, "Can't copy '" + Src.toString() +
               "' to '" + Dest.toString() + "': ");
  return false;
}

bool
Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
  if (reuse_current && !exists())
    return false; // File doesn't exist already, just use it!

  // Reserve space for -XXXXXX at the end.
  char *FNBuffer = (char*) alloca(path.size()+8);
  unsigned offset = path.size();
  path.copy(FNBuffer, offset);

  // Find a numeric suffix that isn't used by an existing file.  Assume there
  // won't be more than 1 million files with the same prefix.  Probably a safe
  // bet.
  static unsigned FCounter = 0;
  do {
    sprintf(FNBuffer+offset, "-%06u", FCounter);
    if (++FCounter > 999999)
      FCounter = 0;
    path = FNBuffer;
  } while (exists());
  return false;
}

bool
Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
  // Make this into a unique file name
  makeUnique(reuse_current, ErrMsg);

  // Now go and create it
  HANDLE h = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW,
                        FILE_ATTRIBUTE_NORMAL, NULL);
  if (h == INVALID_HANDLE_VALUE)
    return MakeErrMsg(ErrMsg, path + ": can't create file");

  CloseHandle(h);
  return false;
}

/// MapInFilePages - Not yet implemented on win32.
const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
  return 0;
}

/// MapInFilePages - Not yet implemented on win32.
void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
  assert(0 && "NOT IMPLEMENTED");
}

}
}
