//===- Path.cpp -----------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "mcld/Support/FileSystem.h"
#include "mcld/Support/Path.h"
#include <llvm/ADT/StringRef.h>

#include <locale>
#include <string.h>
#include <istream>
#include <ostream>

using namespace mcld;
using namespace mcld::sys::fs;

//===--------------------------------------------------------------------===//
// Path
Path::Path()
  : m_PathName() {
}

Path::Path(const Path::ValueType* s )
  : m_PathName(s) {
}

Path::Path(const Path::StringType &s )
  : m_PathName(s) {
}

Path::Path(const Path& pCopy)
 : m_PathName(pCopy.m_PathName) {
}

Path::~Path()
{
}

bool Path::isFromRoot() const
{
  if (m_PathName.empty())
    return false;
  return (separator == m_PathName[0]);
}

bool Path::isFromPWD() const
{
  if (2 > m_PathName.size())
    return false;
  return ('.' == m_PathName[0] && separator == m_PathName[1]);
}

Path& Path::assign(const Path::StringType &s)
{
  m_PathName.assign(s);
  return *this;
}

Path& Path::assign(const Path::ValueType* s, unsigned int length)
{
  if (0 == s || 0 == length)
    assert(0 && "assign a null or empty string to Path");
  m_PathName.assign(s, length);
  return *this;
}

//a,/b a/,b a/,b/ a,b is a/b
Path& Path::append(const Path& pPath)
{
  //first path is a/,second path is /b
  if(m_PathName[m_PathName.length()-1] == separator &&
     pPath.native()[0] == separator) {
    unsigned int old_size = m_PathName.size()-1;
    unsigned int new_size = old_size + pPath.native().size();

    m_PathName.resize(new_size);
    strcpy(const_cast<char*>(m_PathName.data()+old_size), pPath.native().data());
  }
  //first path is a,second path is b
  else if(this->string()[this->native().size()-1] != separator &&
          pPath.string()[0] != separator) {
    m_PathName.append("/");
    m_PathName.append(pPath.native());
  }
  // a/,b or a,/b just append
  else {
    m_PathName.append(pPath.native());
  }
  return *this;
}

bool Path::empty() const
{
  return m_PathName.empty();
}

std::string Path::string() const
{
  return m_PathName;
}

Path::StringType Path::generic_string() const
{
  std::string result = m_PathName;
  detail::canonicalize(result);
  return result;
}

bool Path::canonicalize()
{
  return detail::canonicalize(m_PathName);
}

Path::StringType::size_type Path::m_append_separator_if_needed()
{
  if (!m_PathName.empty() &&
#if defined(MCLD_ON_WIN32)
      *(m_PathName.end()-1) != colon &&
#endif
      !is_separator(*(m_PathName.end()-1))) {
        StringType::size_type tmp(m_PathName.size());
        m_PathName += preferred_separator;
        return tmp;
  }
  return 0;
}

void Path::m_erase_redundant_separator(Path::StringType::size_type pSepPos)
{
  size_t begin=pSepPos;
  // skip '/'
  while(separator == m_PathName[pSepPos])
    ++pSepPos;

  if(begin!=pSepPos)
    m_PathName.erase(begin+1,pSepPos-begin-1);
}

Path Path::stem() const
{
  size_t begin_pos = m_PathName.find_last_of(separator)+1;
  size_t end_pos   = m_PathName.find_last_of(".");
  Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
  return result_path;
}

Path Path::extension() const
{
  size_t begin_pos = m_PathName.find_last_of('.');
  Path result_path(m_PathName.substr(begin_pos));
  return result_path;
}

//===--------------------------------------------------------------------===//
// non-member functions
//===--------------------------------------------------------------------===//
bool mcld::sys::fs::operator==(const Path& pLHS,const Path& pRHS)
{
  return (pLHS.generic_string()==pRHS.generic_string());
}

bool mcld::sys::fs::operator!=(const Path& pLHS,const Path& pRHS)
{
  return !(pLHS==pRHS);
}

Path mcld::sys::fs::operator+(const Path& pLHS, const Path& pRHS)
{
  mcld::sys::fs::Path result = pLHS;
  result.append(pRHS);
  return result;
}

bool mcld::sys::fs::is_separator(char value)
{
  return (value == separator
#if defined(MCLD_ON_WIN32)
          || value == preferred_separator
#endif
          );
}

bool mcld::sys::fs::exists(const Path &pPath)
{
  FileStatus pFileStatus;
  detail::status(pPath, pFileStatus);
  return exists(pFileStatus);
}

bool mcld::sys::fs::is_directory(const Path &pPath)
{
  FileStatus pFileStatus;
  detail::status(pPath, pFileStatus);
  return is_directory(pFileStatus);
}

std::ostream &mcld::sys::fs::operator<<(std::ostream& pOS,
                                        const Path& pPath)
{
  return pOS << pPath.native();
}

std::istream &mcld::sys::fs::operator>>(std::istream& pOS,
                                        Path& pPath)
{
  return pOS >> pPath.native();
}

llvm::raw_ostream &mcld::sys::fs::operator<<(llvm::raw_ostream &pOS,
                                             const Path &pPath)
{
  return pOS << pPath.native();
}

