// Copyright 2014 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_fsevents.h"

#include <dispatch/dispatch.h>

#include <list>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_task_runner_handle.h"

namespace base {

namespace {

// The latency parameter passed to FSEventsStreamCreate().
const CFAbsoluteTime kEventLatencySeconds = 0.3;

// Resolve any symlinks in the path.
FilePath ResolvePath(const FilePath& path) {
  const unsigned kMaxLinksToResolve = 255;

  std::vector<FilePath::StringType> component_vector;
  path.GetComponents(&component_vector);
  std::list<FilePath::StringType>
      components(component_vector.begin(), component_vector.end());

  FilePath result;
  unsigned resolve_count = 0;
  while (resolve_count < kMaxLinksToResolve && !components.empty()) {
    FilePath component(*components.begin());
    components.pop_front();

    FilePath current;
    if (component.IsAbsolute()) {
      current = component;
    } else {
      current = result.Append(component);
    }

    FilePath target;
    if (ReadSymbolicLink(current, &target)) {
      if (target.IsAbsolute())
        result.clear();
      std::vector<FilePath::StringType> target_components;
      target.GetComponents(&target_components);
      components.insert(components.begin(), target_components.begin(),
                        target_components.end());
      resolve_count++;
    } else {
      result = current;
    }
  }

  if (resolve_count >= kMaxLinksToResolve)
    result.clear();
  return result;
}

}  // namespace

FilePathWatcherFSEvents::FilePathWatcherFSEvents()
    : queue_(dispatch_queue_create(
          base::StringPrintf("org.chromium.base.FilePathWatcher.%p", this)
              .c_str(),
          DISPATCH_QUEUE_SERIAL)),
      fsevent_stream_(nullptr),
      weak_factory_(this) {}

FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {
  DCHECK(!task_runner() || task_runner()->RunsTasksInCurrentSequence());
  DCHECK(callback_.is_null())
      << "Cancel() must be called before FilePathWatcher is destroyed.";
}

bool FilePathWatcherFSEvents::Watch(const FilePath& path,
                                    bool recursive,
                                    const FilePathWatcher::Callback& callback) {
  DCHECK(!callback.is_null());
  DCHECK(callback_.is_null());

  // This class could support non-recursive watches, but that is currently
  // left to FilePathWatcherKQueue.
  if (!recursive)
    return false;

  set_task_runner(SequencedTaskRunnerHandle::Get());
  callback_ = callback;

  FSEventStreamEventId start_event = FSEventsGetCurrentEventId();
  // The block runtime would implicitly capture the reference, not the object
  // it's referencing. Copy the path into a local, so that the value is
  // captured by the block's scope.
  const FilePath path_copy(path);

  dispatch_async(queue_, ^{
      StartEventStream(start_event, path_copy);
  });
  return true;
}

void FilePathWatcherFSEvents::Cancel() {
  set_cancelled();
  callback_.Reset();

  // Switch to the dispatch queue to tear down the event stream. As the queue is
  // owned by |this|, and this method is called from the destructor, execute the
  // block synchronously.
  dispatch_sync(queue_, ^{
    if (fsevent_stream_) {
      DestroyEventStream();
      target_.clear();
      resolved_target_.clear();
    }
  });
}

// static
void FilePathWatcherFSEvents::FSEventsCallback(
    ConstFSEventStreamRef stream,
    void* event_watcher,
    size_t num_events,
    void* event_paths,
    const FSEventStreamEventFlags flags[],
    const FSEventStreamEventId event_ids[]) {
  FilePathWatcherFSEvents* watcher =
      reinterpret_cast<FilePathWatcherFSEvents*>(event_watcher);
  bool root_changed = watcher->ResolveTargetPath();
  std::vector<FilePath> paths;
  FSEventStreamEventId root_change_at = FSEventStreamGetLatestEventId(stream);
  for (size_t i = 0; i < num_events; i++) {
    if (flags[i] & kFSEventStreamEventFlagRootChanged)
      root_changed = true;
    if (event_ids[i])
      root_change_at = std::min(root_change_at, event_ids[i]);
    paths.push_back(FilePath(
        reinterpret_cast<char**>(event_paths)[i]).StripTrailingSeparators());
  }

  // Reinitialize the event stream if we find changes to the root. This is
  // necessary since FSEvents doesn't report any events for the subtree after
  // the directory to be watched gets created.
  if (root_changed) {
    // Resetting the event stream from within the callback fails (FSEvents spews
    // bad file descriptor errors), so do the reset asynchronously.
    //
    // We can't dispatch_async a call to UpdateEventStream() directly because
    // there would be no guarantee that |watcher| still exists when it runs.
    //
    // Instead, bounce on task_runner() and use a WeakPtr to verify that
    // |watcher| still exists. If it does, dispatch_async a call to
    // UpdateEventStream(). Because the destructor of |watcher| runs on
    // task_runner() and calls dispatch_sync, it is guaranteed that |watcher|
    // still exists when UpdateEventStream() runs.
    watcher->task_runner()->PostTask(
        FROM_HERE, Bind(
                       [](WeakPtr<FilePathWatcherFSEvents> weak_watcher,
                          FSEventStreamEventId root_change_at) {
                         if (!weak_watcher)
                           return;
                         FilePathWatcherFSEvents* watcher = weak_watcher.get();
                         dispatch_async(watcher->queue_, ^{
                           watcher->UpdateEventStream(root_change_at);
                         });
                       },
                       watcher->weak_factory_.GetWeakPtr(), root_change_at));
  }

  watcher->OnFilePathsChanged(paths);
}

void FilePathWatcherFSEvents::OnFilePathsChanged(
    const std::vector<FilePath>& paths) {
  DCHECK(!resolved_target_.empty());
  task_runner()->PostTask(
      FROM_HERE,
      Bind(&FilePathWatcherFSEvents::DispatchEvents, weak_factory_.GetWeakPtr(),
           paths, target_, resolved_target_));
}

void FilePathWatcherFSEvents::DispatchEvents(const std::vector<FilePath>& paths,
                                             const FilePath& target,
                                             const FilePath& resolved_target) {
  DCHECK(task_runner()->RunsTasksInCurrentSequence());

  // Don't issue callbacks after Cancel() has been called.
  if (is_cancelled() || callback_.is_null()) {
    return;
  }

  for (const FilePath& path : paths) {
    if (resolved_target.IsParent(path) || resolved_target == path) {
      callback_.Run(target, false);
      return;
    }
  }
}

void FilePathWatcherFSEvents::UpdateEventStream(
    FSEventStreamEventId start_event) {
  // It can happen that the watcher gets canceled while tasks that call this
  // function are still in flight, so abort if this situation is detected.
  if (resolved_target_.empty())
    return;

  if (fsevent_stream_)
    DestroyEventStream();

  ScopedCFTypeRef<CFStringRef> cf_path(CFStringCreateWithCString(
      NULL, resolved_target_.value().c_str(), kCFStringEncodingMacHFS));
  ScopedCFTypeRef<CFStringRef> cf_dir_path(CFStringCreateWithCString(
      NULL, resolved_target_.DirName().value().c_str(),
      kCFStringEncodingMacHFS));
  CFStringRef paths_array[] = { cf_path.get(), cf_dir_path.get() };
  ScopedCFTypeRef<CFArrayRef> watched_paths(CFArrayCreate(
      NULL, reinterpret_cast<const void**>(paths_array), arraysize(paths_array),
      &kCFTypeArrayCallBacks));

  FSEventStreamContext context;
  context.version = 0;
  context.info = this;
  context.retain = NULL;
  context.release = NULL;
  context.copyDescription = NULL;

  fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context,
                                        watched_paths,
                                        start_event,
                                        kEventLatencySeconds,
                                        kFSEventStreamCreateFlagWatchRoot);
  FSEventStreamSetDispatchQueue(fsevent_stream_, queue_);

  if (!FSEventStreamStart(fsevent_stream_)) {
    task_runner()->PostTask(FROM_HERE,
                            Bind(&FilePathWatcherFSEvents::ReportError,
                                 weak_factory_.GetWeakPtr(), target_));
  }
}

bool FilePathWatcherFSEvents::ResolveTargetPath() {
  FilePath resolved = ResolvePath(target_).StripTrailingSeparators();
  bool changed = resolved != resolved_target_;
  resolved_target_ = resolved;
  if (resolved_target_.empty()) {
    task_runner()->PostTask(FROM_HERE,
                            Bind(&FilePathWatcherFSEvents::ReportError,
                                 weak_factory_.GetWeakPtr(), target_));
  }
  return changed;
}

void FilePathWatcherFSEvents::ReportError(const FilePath& target) {
  DCHECK(task_runner()->RunsTasksInCurrentSequence());
  if (!callback_.is_null()) {
    callback_.Run(target, true);
  }
}

void FilePathWatcherFSEvents::DestroyEventStream() {
  FSEventStreamStop(fsevent_stream_);
  FSEventStreamInvalidate(fsevent_stream_);
  FSEventStreamRelease(fsevent_stream_);
  fsevent_stream_ = NULL;
}

void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event,
                                               const FilePath& path) {
  DCHECK(resolved_target_.empty());

  target_ = path;
  ResolveTargetPath();
  UpdateEventStream(start_event);
}

}  // namespace base
