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

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

namespace { // anonymous

bool status_known(FileStatus f)
{
  return f.type() != StatusError;
}

bool is_symlink(FileStatus f)
{
  return f.type() == SymlinkFile;
}

} // namespace of anonymous

//===----------------------------------------------------------------------===//
// Directory
//===----------------------------------------------------------------------===//
Directory::Directory()
  : m_Path(),
    m_FileStatus(),
    m_SymLinkStatus(),
    m_Handler(0),
    m_Cache(),
    m_CacheFull(false) {
}

Directory::Directory(const Path& pPath,
                     FileStatus st,
                     FileStatus symlink_st)
  : m_Path(pPath),
    m_FileStatus(st),
    m_SymLinkStatus(symlink_st),
    m_Handler(0),
    m_Cache(),
    m_CacheFull(false) {
  if (m_Path.native() == ".")
    detail::get_pwd(m_Path.native());
  m_Path.m_append_separator_if_needed();
  mcld::sys::fs::detail::open_dir(*this);
}

Directory::Directory(const Directory& pCopy)
  : m_Path(pCopy.m_Path),
    m_FileStatus(pCopy.m_FileStatus),
    m_SymLinkStatus(pCopy.m_SymLinkStatus),
    m_Handler(0),
    m_Cache(),
    m_CacheFull(false) {
  mcld::sys::fs::detail::open_dir(*this);
}

Directory::~Directory()
{
  detail::close_dir(*this);
}

bool Directory::isGood() const
{
  return (0 != m_Handler);
}

Directory& Directory::operator=(const Directory& pCopy)
{
  assign(pCopy.m_Path, pCopy.m_FileStatus, pCopy.m_SymLinkStatus);
  return *this;
}

void Directory::assign(const Path& pPath,
                       FileStatus st,
                       FileStatus symlink_st)
{
  if (isGood())
    clear();

  m_Path = pPath;
  if (m_Path.native() == ".")
    detail::get_pwd(m_Path.native());
  m_Path.m_append_separator_if_needed();

  m_FileStatus = st;
  m_SymLinkStatus = symlink_st;
  detail::open_dir(*this);
}

FileStatus Directory::status() const
{
  if (!status_known(m_FileStatus))
  {
    // optimization: if the symlink status is known, and it isn't a symlink,
    // then status and symlink_status are identical so just copy the
    // symlink status to the regular status.
    if (status_known(m_SymLinkStatus)
      && !is_symlink(m_SymLinkStatus))
    {
      m_FileStatus = m_SymLinkStatus;
    }
    else detail::status(m_Path,m_FileStatus);
  }
  return m_FileStatus;

}

FileStatus Directory::symlinkStatus() const
{
  if (!status_known(m_SymLinkStatus))
     detail::symlink_status(m_Path,m_SymLinkStatus);
  return  m_SymLinkStatus;
}

Directory::iterator Directory::begin()
{
  if (m_CacheFull && m_Cache.empty())
    return end();
  PathCache::iterator iter = m_Cache.begin();
  if (NULL == iter.getEntry())
    ++iter;
  return iterator(this, iter);
}

Directory::iterator Directory::end()
{
  return iterator(0, m_Cache.end());
}

void Directory::clear()
{
  m_Path.native().clear();
  m_FileStatus = FileStatus();
  m_SymLinkStatus = FileStatus();
  m_Cache.clear();
  detail::close_dir(*this);
}

//==========================
// DirIterator
DirIterator::DirIterator(Directory* pParent,
                         const DirIterator::DirCache::iterator& pIter)
  : m_pParent(pParent),
    m_Iter(pIter) {
  m_pEntry = m_Iter.getEntry();
}

DirIterator::DirIterator(const DirIterator& pCopy)
  : m_pParent(pCopy.m_pParent),
    m_Iter(pCopy.m_Iter),
    m_pEntry(pCopy.m_pEntry) {
}

DirIterator::~DirIterator()
{
}

Path* DirIterator::path()
{
  if (NULL == m_pParent)
    return NULL;
  return &m_pEntry->value();
}

const Path* DirIterator::path() const
{
  if (NULL == m_pParent)
    return NULL;
  return &m_pEntry->value();
}

DirIterator& DirIterator::operator=(const DirIterator& pCopy)
{
  m_pParent = pCopy.m_pParent;
  m_Iter = pCopy.m_Iter;
  m_pEntry = pCopy.m_pEntry;
  return (*this);
}

DirIterator& DirIterator::operator++()
{
  if (0 == m_pParent)
    return *this;

  // move forward one step first.
  ++m_Iter;

  if (m_pParent->m_Cache.end() == m_Iter) {
    if (!m_pParent->m_CacheFull) {
      m_pEntry = detail::bring_one_into_cache(*this);
      if (0 == m_pEntry && m_pParent->m_CacheFull)
        m_pParent = 0;
      return *this;
    }
    m_pParent = 0;
    return *this;
  }

  m_pEntry = m_Iter.getEntry();
  return *this;
}

DirIterator DirIterator::operator++(int)
{
  DirIterator tmp(*this);

  // move forward one step first.
  ++m_Iter;

  if (m_pParent->m_Cache.end() == m_Iter) {
    if (!m_pParent->m_CacheFull) {
      m_pEntry = detail::bring_one_into_cache(*this);
      if (0 == m_pEntry && m_pParent->m_CacheFull)
        m_pParent = 0;
      return tmp;
    }
    m_pParent = 0;
    return tmp;
  }

  m_pEntry = m_Iter.getEntry();
  return tmp;
}

bool DirIterator::operator==(const DirIterator& y) const
{
  if (m_pParent != y.m_pParent)
    return false;
  if (0 == m_pParent)
    return true;
  const Path* x_path = path();
  const Path* y_path = y.path();
  if (0 == x_path && 0 == y_path)
    return true;
  if (0 == x_path || 0 == y_path)
    return false;
  return (*x_path == *y_path);
}

bool DirIterator::operator!=(const DirIterator& y) const
{
  return !this->operator==(y);
}

