/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>

#include "webrtc/base/pathutils.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/stream.h"

#if defined(WEBRTC_WIN)
#include "webrtc/base/win32filesystem.h"
#else
#include "webrtc/base/unixfilesystem.h"
#endif

#if !defined(WEBRTC_WIN)
#define MAX_PATH 260
#endif

namespace rtc {

//////////////////////////
// Directory Iterator   //
//////////////////////////

// A DirectoryIterator is created with a given directory. It originally points
// to the first file in the directory, and can be advanecd with Next(). This
// allows you to get information about each file.

  // Constructor
DirectoryIterator::DirectoryIterator()
#ifdef WEBRTC_WIN
    : handle_(INVALID_HANDLE_VALUE) {
#else
    : dir_(NULL), dirent_(NULL) {
#endif
}

  // Destructor
DirectoryIterator::~DirectoryIterator() {
#if defined(WEBRTC_WIN)
  if (handle_ != INVALID_HANDLE_VALUE)
    ::FindClose(handle_);
#else
  if (dir_)
    closedir(dir_);
#endif
}

  // Starts traversing a directory.
  // dir is the directory to traverse
  // returns true if the directory exists and is valid
bool DirectoryIterator::Iterate(const Pathname &dir) {
  directory_ = dir.pathname();
#if defined(WEBRTC_WIN)
  if (handle_ != INVALID_HANDLE_VALUE)
    ::FindClose(handle_);
  std::string d = dir.pathname() + '*';
  handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_);
  if (handle_ == INVALID_HANDLE_VALUE)
    return false;
#else
  if (dir_ != NULL)
    closedir(dir_);
  dir_ = ::opendir(directory_.c_str());
  if (dir_ == NULL)
    return false;
  dirent_ = readdir(dir_);
  if (dirent_ == NULL)
    return false;

  if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0)
    return false;
#endif
  return true;
}

  // Advances to the next file
  // returns true if there were more files in the directory.
bool DirectoryIterator::Next() {
#if defined(WEBRTC_WIN)
  return ::FindNextFile(handle_, &data_) == TRUE;
#else
  dirent_ = ::readdir(dir_);
  if (dirent_ == NULL)
    return false;

  return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0;
#endif
}

  // returns true if the file currently pointed to is a directory
bool DirectoryIterator::IsDirectory() const {
#if defined(WEBRTC_WIN)
  return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE;
#else
  return S_ISDIR(stat_.st_mode);
#endif
}

  // returns the name of the file currently pointed to
std::string DirectoryIterator::Name() const {
#if defined(WEBRTC_WIN)
  return ToUtf8(data_.cFileName);
#else
  assert(dirent_ != NULL);
  return dirent_->d_name;
#endif
}

  // returns the size of the file currently pointed to
size_t DirectoryIterator::FileSize() const {
#if !defined(WEBRTC_WIN)
  return stat_.st_size;
#else
  return data_.nFileSizeLow;
#endif
}

bool DirectoryIterator::OlderThan(int seconds) const {
  time_t file_modify_time;
#if defined(WEBRTC_WIN)
  FileTimeToUnixTime(data_.ftLastWriteTime, &file_modify_time);
#else
  file_modify_time = stat_.st_mtime;
#endif
  return TimeDiff(time(NULL), file_modify_time) >= seconds;
}

FilesystemInterface* Filesystem::default_filesystem_ = NULL;

FilesystemInterface *Filesystem::EnsureDefaultFilesystem() {
  if (!default_filesystem_) {
#if defined(WEBRTC_WIN)
    default_filesystem_ = new Win32Filesystem();
#else
    default_filesystem_ = new UnixFilesystem();
#endif
  }
  return default_filesystem_;
}

bool FilesystemInterface::CopyFolder(const Pathname &old_path,
                                     const Pathname &new_path) {
  bool success = true;
  VERIFY(IsFolder(old_path));
  Pathname new_dir;
  new_dir.SetFolder(new_path.pathname());
  Pathname old_dir;
  old_dir.SetFolder(old_path.pathname());
  if (!CreateFolder(new_dir))
    return false;
  DirectoryIterator *di = IterateDirectory();
  if (!di)
    return false;
  if (di->Iterate(old_dir.pathname())) {
    do {
      if (di->Name() == "." || di->Name() == "..")
        continue;
      Pathname source;
      Pathname dest;
      source.SetFolder(old_dir.pathname());
      dest.SetFolder(new_path.pathname());
      source.SetFilename(di->Name());
      dest.SetFilename(di->Name());
      if (!CopyFileOrFolder(source, dest))
        success = false;
    } while (di->Next());
  }
  delete di;
  return success;
}

bool FilesystemInterface::DeleteFolderContents(const Pathname &folder) {
  bool success = true;
  VERIFY(IsFolder(folder));
  DirectoryIterator *di = IterateDirectory();
  if (!di)
    return false;
  if (di->Iterate(folder)) {
    do {
      if (di->Name() == "." || di->Name() == "..")
        continue;
      Pathname subdir;
      subdir.SetFolder(folder.pathname());
      if (di->IsDirectory()) {
        subdir.AppendFolder(di->Name());
        if (!DeleteFolderAndContents(subdir)) {
          success = false;
        }
      } else {
        subdir.SetFilename(di->Name());
        if (!DeleteFile(subdir)) {
          success = false;
        }
      }
    } while (di->Next());
  }
  delete di;
  return success;
}

bool FilesystemInterface::CleanAppTempFolder() {
  Pathname path;
  if (!GetAppTempFolder(&path))
    return false;
  if (IsAbsent(path))
    return true;
  if (!IsTemporaryPath(path)) {
    ASSERT(false);
    return false;
  }
  return DeleteFolderContents(path);
}

Pathname Filesystem::GetCurrentDirectory() {
  return EnsureDefaultFilesystem()->GetCurrentDirectory();
}

bool CreateUniqueFile(Pathname& path, bool create_empty) {
  LOG(LS_INFO) << "Path " << path.pathname() << std::endl;
  // If no folder is supplied, use the temporary folder
  if (path.folder().empty()) {
    Pathname temporary_path;
    if (!Filesystem::GetTemporaryFolder(temporary_path, true, NULL)) {
      printf("Get temp failed\n");
      return false;
    }
    path.SetFolder(temporary_path.pathname());
  }

  // If no filename is supplied, use a temporary name
  if (path.filename().empty()) {
    std::string folder(path.folder());
    std::string filename = Filesystem::TempFilename(folder, "gt");
    path.SetPathname(filename);
    if (!create_empty) {
      Filesystem::DeleteFile(path.pathname());
    }
    return true;
  }

  // Otherwise, create a unique name based on the given filename
  // foo.txt -> foo-N.txt
  const std::string basename = path.basename();
  const size_t MAX_VERSION = 100;
  size_t version = 0;
  while (version < MAX_VERSION) {
    std::string pathname = path.pathname();

    if (!Filesystem::IsFile(pathname)) {
      if (create_empty) {
        FileStream* fs = Filesystem::OpenFile(pathname, "w");
        delete fs;
      }
      return true;
    }
    version += 1;
    char version_base[MAX_PATH];
    sprintfn(version_base, ARRAY_SIZE(version_base), "%s-%u",
             basename.c_str(), version);
    path.SetBasename(version_base);
  }
  return true;
}

}  // namespace rtc
