// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/files/directory_impl.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
#include "services/files/file_impl.h"
#include "services/files/shared_impl.h"
#include "services/files/util.h"

namespace mojo {
namespace files {

namespace {

// Calls |closedir()| on a |DIR*|.
struct DIRDeleter {
  void operator()(DIR* dir) const { PCHECK(closedir(dir) == 0); }
};
typedef scoped_ptr<DIR, DIRDeleter> ScopedDIR;

Error ValidateOpenFlags(uint32_t open_flags, bool is_directory) {
  // Treat unknown flags as "unimplemented".
  if ((open_flags &
       ~(kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive |
         kOpenFlagAppend | kOpenFlagTruncate)))
    return ERROR_UNIMPLEMENTED;

  // At least one of |kOpenFlagRead| or |kOpenFlagWrite| must be set.
  if (!(open_flags & (kOpenFlagRead | kOpenFlagWrite)))
    return ERROR_INVALID_ARGUMENT;

  // |kOpenFlagCreate| requires |kOpenFlagWrite|.
  if ((open_flags & kOpenFlagCreate) && !(open_flags & kOpenFlagWrite))
    return ERROR_INVALID_ARGUMENT;

  // |kOpenFlagExclusive| requires |kOpenFlagCreate|.
  if ((open_flags & kOpenFlagExclusive) && !(open_flags & kOpenFlagCreate))
    return ERROR_INVALID_ARGUMENT;

  if (is_directory) {
    // Check that file-only flags aren't set.
    if ((open_flags & (kOpenFlagAppend | kOpenFlagTruncate)))
      return ERROR_INVALID_ARGUMENT;
    return ERROR_OK;
  }

  // File-only flags:

  // |kOpenFlagAppend| requires |kOpenFlagWrite|.
  if ((open_flags & kOpenFlagAppend) && !(open_flags & kOpenFlagWrite))
    return ERROR_INVALID_ARGUMENT;

  // |kOpenFlagTruncate| requires |kOpenFlagWrite|.
  if ((open_flags & kOpenFlagTruncate) && !(open_flags & kOpenFlagWrite))
    return ERROR_INVALID_ARGUMENT;

  return ERROR_OK;
}

Error ValidateDeleteFlags(uint32_t delete_flags) {
  // Treat unknown flags as "unimplemented".
  if ((delete_flags &
       ~(kDeleteFlagFileOnly | kDeleteFlagDirectoryOnly |
         kDeleteFlagRecursive)))
    return ERROR_UNIMPLEMENTED;

  // Only one of the three currently-defined flags may be set.
  if ((delete_flags & kDeleteFlagFileOnly) &&
      (delete_flags & (kDeleteFlagDirectoryOnly | kDeleteFlagRecursive)))
    return ERROR_INVALID_ARGUMENT;
  if ((delete_flags & kDeleteFlagDirectoryOnly) &&
      (delete_flags & (kDeleteFlagFileOnly | kDeleteFlagRecursive)))
    return ERROR_INVALID_ARGUMENT;
  if ((delete_flags & kDeleteFlagRecursive) &&
      (delete_flags & (kDeleteFlagFileOnly | kDeleteFlagDirectoryOnly)))
    return ERROR_INVALID_ARGUMENT;

  return ERROR_OK;
}

}  // namespace

DirectoryImpl::DirectoryImpl(InterfaceRequest<Directory> request,
                             base::ScopedFD dir_fd,
                             scoped_ptr<base::ScopedTempDir> temp_dir)
    : binding_(this, request.Pass()),
      dir_fd_(dir_fd.Pass()),
      temp_dir_(temp_dir.Pass()) {
  DCHECK(dir_fd_.is_valid());
}

DirectoryImpl::~DirectoryImpl() {
}

void DirectoryImpl::Read(
    const Callback<void(Error, Array<DirectoryEntryPtr>)>& callback) {
  static const size_t kMaxReadCount = 1000;

  DCHECK(dir_fd_.is_valid());

  // |fdopendir()| takes ownership of the FD (giving it to the |DIR| --
  // |closedir()| will close the FD)), so we need to |dup()| ours.
  base::ScopedFD fd(dup(dir_fd_.get()));
  if (!fd.is_valid()) {
    callback.Run(ErrnoToError(errno), Array<DirectoryEntryPtr>());
    return;
  }

  ScopedDIR dir(fdopendir(fd.release()));
  if (!dir) {
    callback.Run(ErrnoToError(errno), Array<DirectoryEntryPtr>());
    return;
  }

  Array<DirectoryEntryPtr> result(0);

// Warning: This is not portable (per POSIX.1 -- |buffer| may not be large
// enough), but it's fine for Linux.
#if !defined(OS_ANDROID) && !defined(OS_LINUX)
#error "Use of struct dirent for readdir_r() buffer not portable; please check."
#endif
  struct dirent buffer;
  for (size_t n = 0;;) {
    struct dirent* entry = nullptr;
    if (int error = readdir_r(dir.get(), &buffer, &entry)) {
      // |error| is effectively an errno (for |readdir_r()|), AFAICT.
      callback.Run(ErrnoToError(error), Array<DirectoryEntryPtr>());
      return;
    }

    if (!entry)
      break;

    n++;
    if (n > kMaxReadCount) {
      LOG(WARNING) << "Directory contents truncated";
      callback.Run(ERROR_OUT_OF_RANGE, result.Pass());
      return;
    }

    DirectoryEntryPtr e = DirectoryEntry::New();
    switch (entry->d_type) {
      case DT_DIR:
        e->type = FILE_TYPE_DIRECTORY;
        break;
      case DT_REG:
        e->type = FILE_TYPE_REGULAR_FILE;
        break;
      default:
        e->type = FILE_TYPE_UNKNOWN;
        break;
    }
    e->name = String(entry->d_name);
    result.push_back(e.Pass());
  }

  callback.Run(ERROR_OK, result.Pass());
}

void DirectoryImpl::Stat(
    const Callback<void(Error, FileInformationPtr)>& callback) {
  DCHECK(dir_fd_.is_valid());
  StatFD(dir_fd_.get(), callback);
}

void DirectoryImpl::Touch(TimespecOrNowPtr atime,
                          TimespecOrNowPtr mtime,
                          const Callback<void(Error)>& callback) {
  DCHECK(dir_fd_.is_valid());
  TouchFD(dir_fd_.get(), atime.Pass(), mtime.Pass(), callback);
}

// TODO(vtl): Move the implementation to a thread pool.
void DirectoryImpl::OpenFile(const String& path,
                             InterfaceRequest<File> file,
                             uint32_t open_flags,
                             const Callback<void(Error)>& callback) {
  DCHECK(!path.is_null());
  DCHECK(dir_fd_.is_valid());

  if (Error error = IsPathValid(path)) {
    callback.Run(error);
    return;
  }
  // TODO(vtl): Make sure the path doesn't exit this directory (if appropriate).
  // TODO(vtl): Maybe allow absolute paths?

  if (Error error = ValidateOpenFlags(open_flags, false)) {
    callback.Run(error);
    return;
  }

  int flags = 0;
  if ((open_flags & kOpenFlagRead))
    flags |= (open_flags & kOpenFlagWrite) ? O_RDWR : O_RDONLY;
  else
    flags |= O_WRONLY;
  if ((open_flags & kOpenFlagCreate))
    flags |= O_CREAT;
  if ((open_flags & kOpenFlagExclusive))
    flags |= O_EXCL;
  if ((open_flags & kOpenFlagAppend))
    flags |= O_APPEND;
  if ((open_flags & kOpenFlagTruncate))
    flags |= O_TRUNC;

  base::ScopedFD file_fd(
      HANDLE_EINTR(openat(dir_fd_.get(), path.get().c_str(), flags, 0600)));
  if (!file_fd.is_valid()) {
    callback.Run(ErrnoToError(errno));
    return;
  }

  if (file.is_pending())
    new FileImpl(file.Pass(), file_fd.Pass());
  callback.Run(ERROR_OK);
}

void DirectoryImpl::OpenDirectory(const String& path,
                                  InterfaceRequest<Directory> directory,
                                  uint32_t open_flags,
                                  const Callback<void(Error)>& callback) {
  DCHECK(!path.is_null());
  DCHECK(dir_fd_.is_valid());

  if (Error error = IsPathValid(path)) {
    callback.Run(error);
    return;
  }
  // TODO(vtl): Make sure the path doesn't exit this directory (if appropriate).
  // TODO(vtl): Maybe allow absolute paths?

  if (Error error = ValidateOpenFlags(open_flags, false)) {
    callback.Run(error);
    return;
  }

  // TODO(vtl): Implement read-only (whatever that means).
  if (!(open_flags & kOpenFlagWrite)) {
    callback.Run(ERROR_UNIMPLEMENTED);
    return;
  }

  if ((open_flags & kOpenFlagCreate)) {
    if (mkdirat(dir_fd_.get(), path.get().c_str(), 0700) != 0) {
      // Allow |EEXIST| if |kOpenFlagExclusive| is not set. Note, however, that
      // it does not guarantee that |path| is a directory.
      // TODO(vtl): Hrm, ponder if we should check that |path| is a directory.
      if (errno != EEXIST || !(open_flags & kOpenFlagExclusive)) {
        callback.Run(ErrnoToError(errno));
        return;
      }
    }
  }

  base::ScopedFD new_dir_fd(
      HANDLE_EINTR(openat(dir_fd_.get(), path.get().c_str(), O_DIRECTORY, 0)));
  if (!new_dir_fd.is_valid()) {
    callback.Run(ErrnoToError(errno));
    return;
  }

  if (directory.is_pending())
    new DirectoryImpl(directory.Pass(), new_dir_fd.Pass(), nullptr);
  callback.Run(ERROR_OK);
}

void DirectoryImpl::Rename(const String& path,
                           const String& new_path,
                           const Callback<void(Error)>& callback) {
  DCHECK(!path.is_null());
  DCHECK(!new_path.is_null());
  DCHECK(dir_fd_.is_valid());

  if (Error error = IsPathValid(path)) {
    callback.Run(error);
    return;
  }
  if (Error error = IsPathValid(new_path)) {
    callback.Run(error);
    return;
  }
  // TODO(vtl): See TODOs about |path| in OpenFile().

  if (renameat(dir_fd_.get(), path.get().c_str(), dir_fd_.get(),
               new_path.get().c_str())) {
    callback.Run(ErrnoToError(errno));
    return;
  }

  callback.Run(ERROR_OK);
}

void DirectoryImpl::Delete(const String& path,
                           uint32_t delete_flags,
                           const Callback<void(Error)>& callback) {
  DCHECK(!path.is_null());
  DCHECK(dir_fd_.is_valid());

  if (Error error = IsPathValid(path)) {
    callback.Run(error);
    return;
  }
  // TODO(vtl): See TODOs about |path| in OpenFile().

  if (Error error = ValidateDeleteFlags(delete_flags)) {
    callback.Run(error);
    return;
  }

  // TODO(vtl): Recursive not yet supported.
  if ((delete_flags & kDeleteFlagRecursive)) {
    callback.Run(ERROR_UNIMPLEMENTED);
    return;
  }

  // First try deleting it as a file, unless we're told to do directory-only.
  if (!(delete_flags & kDeleteFlagDirectoryOnly)) {
    if (unlinkat(dir_fd_.get(), path.get().c_str(), 0) == 0) {
      callback.Run(ERROR_OK);
      return;
    }

    // If file-only, don't continue.
    if ((delete_flags & kDeleteFlagFileOnly)) {
      callback.Run(ErrnoToError(errno));
      return;
    }
  }

  // Try deleting it as a directory.
  if (unlinkat(dir_fd_.get(), path.get().c_str(), AT_REMOVEDIR) == 0) {
    callback.Run(ERROR_OK);
    return;
  }

  callback.Run(ErrnoToError(errno));
}

}  // namespace files
}  // namespace mojo
