// Copyright (c) 2011 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 "base/files/file_path_watcher.h"

#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/time/time.h"
#include "base/win/object_watcher.h"

namespace base {

namespace {

class FilePathWatcherImpl : public FilePathWatcher::PlatformDelegate,
                            public base::win::ObjectWatcher::Delegate,
                            public MessageLoop::DestructionObserver {
 public:
  FilePathWatcherImpl()
      : handle_(INVALID_HANDLE_VALUE),
        recursive_watch_(false) {}

  // FilePathWatcher::PlatformDelegate overrides.
  virtual bool Watch(const FilePath& path,
                     bool recursive,
                     const FilePathWatcher::Callback& callback) OVERRIDE;
  virtual void Cancel() OVERRIDE;

  // Deletion of the FilePathWatcher will call Cancel() to dispose of this
  // object in the right thread. This also observes destruction of the required
  // cleanup thread, in case it quits before Cancel() is called.
  virtual void WillDestroyCurrentMessageLoop() OVERRIDE;

  // Callback from MessageLoopForIO.
  virtual void OnObjectSignaled(HANDLE object);

 private:
  virtual ~FilePathWatcherImpl() {}

  // Setup a watch handle for directory |dir|. Set |recursive| to true to watch
  // the directory sub trees. Returns true if no fatal error occurs. |handle|
  // will receive the handle value if |dir| is watchable, otherwise
  // INVALID_HANDLE_VALUE.
  static bool SetupWatchHandle(const FilePath& dir,
                               bool recursive,
                               HANDLE* handle) WARN_UNUSED_RESULT;

  // (Re-)Initialize the watch handle.
  bool UpdateWatch() WARN_UNUSED_RESULT;

  // Destroy the watch handle.
  void DestroyWatch();

  // Cleans up and stops observing the |message_loop_| thread.
  void CancelOnMessageLoopThread() OVERRIDE;

  // Callback to notify upon changes.
  FilePathWatcher::Callback callback_;

  // Path we're supposed to watch (passed to callback).
  FilePath target_;

  // Handle for FindFirstChangeNotification.
  HANDLE handle_;

  // ObjectWatcher to watch handle_ for events.
  base::win::ObjectWatcher watcher_;

  // Set to true to watch the sub trees of the specified directory file path.
  bool recursive_watch_;

  // Keep track of the last modified time of the file.  We use nulltime
  // to represent the file not existing.
  base::Time last_modified_;

  // The time at which we processed the first notification with the
  // |last_modified_| time stamp.
  base::Time first_notification_;

  DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
};

bool FilePathWatcherImpl::Watch(const FilePath& path,
                                bool recursive,
                                const FilePathWatcher::Callback& callback) {
  DCHECK(target_.value().empty());  // Can only watch one path.

  set_message_loop(base::MessageLoopProxy::current());
  callback_ = callback;
  target_ = path;
  recursive_watch_ = recursive;
  MessageLoop::current()->AddDestructionObserver(this);

  if (!UpdateWatch())
    return false;

  watcher_.StartWatching(handle_, this);

  return true;
}

void FilePathWatcherImpl::Cancel() {
  if (callback_.is_null()) {
    // Watch was never called, or the |message_loop_| has already quit.
    set_cancelled();
    return;
  }

  // Switch to the file thread if necessary so we can stop |watcher_|.
  if (!message_loop()->BelongsToCurrentThread()) {
    message_loop()->PostTask(FROM_HERE,
                             base::Bind(&FilePathWatcher::CancelWatch,
                                        make_scoped_refptr(this)));
  } else {
    CancelOnMessageLoopThread();
  }
}

void FilePathWatcherImpl::CancelOnMessageLoopThread() {
  set_cancelled();

  if (handle_ != INVALID_HANDLE_VALUE)
    DestroyWatch();

  if (!callback_.is_null()) {
    MessageLoop::current()->RemoveDestructionObserver(this);
    callback_.Reset();
  }
}

void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
  CancelOnMessageLoopThread();
}

void FilePathWatcherImpl::OnObjectSignaled(HANDLE object) {
  DCHECK(object == handle_);
  // Make sure we stay alive through the body of this function.
  scoped_refptr<FilePathWatcherImpl> keep_alive(this);

  if (!UpdateWatch()) {
    callback_.Run(target_, true /* error */);
    return;
  }

  // Check whether the event applies to |target_| and notify the callback.
  base::PlatformFileInfo file_info;
  bool file_exists = file_util::GetFileInfo(target_, &file_info);
  if (file_exists && (last_modified_.is_null() ||
      last_modified_ != file_info.last_modified)) {
    last_modified_ = file_info.last_modified;
    first_notification_ = base::Time::Now();
    callback_.Run(target_, false);
  } else if (file_exists && !first_notification_.is_null()) {
    // The target's last modification time is equal to what's on record. This
    // means that either an unrelated event occurred, or the target changed
    // again (file modification times only have a resolution of 1s). Comparing
    // file modification times against the wall clock is not reliable to find
    // out whether the change is recent, since this code might just run too
    // late. Moreover, there's no guarantee that file modification time and wall
    // clock times come from the same source.
    //
    // Instead, the time at which the first notification carrying the current
    // |last_notified_| time stamp is recorded. Later notifications that find
    // the same file modification time only need to be forwarded until wall
    // clock has advanced one second from the initial notification. After that
    // interval, client code is guaranteed to having seen the current revision
    // of the file.
    if (base::Time::Now() - first_notification_ >
        base::TimeDelta::FromSeconds(1)) {
      // Stop further notifications for this |last_modification_| time stamp.
      first_notification_ = base::Time();
    }
    callback_.Run(target_, false);
  } else if (!file_exists && !last_modified_.is_null()) {
    last_modified_ = base::Time();
    callback_.Run(target_, false);
  }

  // The watch may have been cancelled by the callback.
  if (handle_ != INVALID_HANDLE_VALUE)
    watcher_.StartWatching(handle_, this);
}

// static
bool FilePathWatcherImpl::SetupWatchHandle(const FilePath& dir,
                                           bool recursive,
                                           HANDLE* handle) {
  *handle = FindFirstChangeNotification(
      dir.value().c_str(),
      recursive,
      FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE |
      FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_DIR_NAME |
      FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SECURITY);
  if (*handle != INVALID_HANDLE_VALUE) {
    // Make sure the handle we got points to an existing directory. It seems
    // that windows sometimes hands out watches to directories that are
    // about to go away, but doesn't sent notifications if that happens.
    if (!DirectoryExists(dir)) {
      FindCloseChangeNotification(*handle);
      *handle = INVALID_HANDLE_VALUE;
    }
    return true;
  }

  // If FindFirstChangeNotification failed because the target directory
  // doesn't exist, access is denied (happens if the file is already gone but
  // there are still handles open), or the target is not a directory, try the
  // immediate parent directory instead.
  DWORD error_code = GetLastError();
  if (error_code != ERROR_FILE_NOT_FOUND &&
      error_code != ERROR_PATH_NOT_FOUND &&
      error_code != ERROR_ACCESS_DENIED &&
      error_code != ERROR_SHARING_VIOLATION &&
      error_code != ERROR_DIRECTORY) {
    using ::operator<<; // Pick the right operator<< below.
    DPLOG(ERROR) << "FindFirstChangeNotification failed for "
                 << dir.value();
    return false;
  }

  return true;
}

bool FilePathWatcherImpl::UpdateWatch() {
  if (handle_ != INVALID_HANDLE_VALUE)
    DestroyWatch();

  base::PlatformFileInfo file_info;
  if (file_util::GetFileInfo(target_, &file_info)) {
    last_modified_ = file_info.last_modified;
    first_notification_ = base::Time::Now();
  }

  // Start at the target and walk up the directory chain until we succesfully
  // create a watch handle in |handle_|. |child_dirs| keeps a stack of child
  // directories stripped from target, in reverse order.
  std::vector<FilePath> child_dirs;
  FilePath watched_path(target_);
  while (true) {
    if (!SetupWatchHandle(watched_path, recursive_watch_, &handle_))
      return false;

    // Break if a valid handle is returned. Try the parent directory otherwise.
    if (handle_ != INVALID_HANDLE_VALUE)
      break;

    // Abort if we hit the root directory.
    child_dirs.push_back(watched_path.BaseName());
    FilePath parent(watched_path.DirName());
    if (parent == watched_path) {
      DLOG(ERROR) << "Reached the root directory";
      return false;
    }
    watched_path = parent;
  }

  // At this point, handle_ is valid. However, the bottom-up search that the
  // above code performs races against directory creation. So try to walk back
  // down and see whether any children appeared in the mean time.
  while (!child_dirs.empty()) {
    watched_path = watched_path.Append(child_dirs.back());
    child_dirs.pop_back();
    HANDLE temp_handle = INVALID_HANDLE_VALUE;
    if (!SetupWatchHandle(watched_path, recursive_watch_, &temp_handle))
      return false;
    if (temp_handle == INVALID_HANDLE_VALUE)
      break;
    FindCloseChangeNotification(handle_);
    handle_ = temp_handle;
  }

  return true;
}

void FilePathWatcherImpl::DestroyWatch() {
  watcher_.StopWatching();
  FindCloseChangeNotification(handle_);
  handle_ = INVALID_HANDLE_VALUE;
}

}  // namespace

FilePathWatcher::FilePathWatcher() {
  impl_ = new FilePathWatcherImpl();
}

}  // namespace base
