// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(TARGET_OS_MACOS)

#include "bin/file_system_watcher.h"

#include <errno.h>  // NOLINT
#include <fcntl.h>  // NOLINT
#include <unistd.h>  // NOLINT
#include <CoreServices/CoreServices.h>  // NOLINT

#include "bin/eventhandler.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/socket.h"
#include "bin/thread.h"

#include "platform/signal_blocker.h"


#ifndef MAC_OS_X_VERSION_10_7
enum {
  kFSEventStreamCreateFlagFileEvents = 0x00000010
};
enum {
  kFSEventStreamEventFlagItemCreated = 0x00000100,
  kFSEventStreamEventFlagItemRemoved = 0x00000200,
  kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400,
  kFSEventStreamEventFlagItemRenamed = 0x00000800,
  kFSEventStreamEventFlagItemModified = 0x00001000,
  kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000,
  kFSEventStreamEventFlagItemChangeOwner = 0x00004000,
  kFSEventStreamEventFlagItemXattrMod = 0x00008000,
  kFSEventStreamEventFlagItemIsFile = 0x00010000,
  kFSEventStreamEventFlagItemIsDir = 0x00020000,
  kFSEventStreamEventFlagItemIsSymlink = 0x00040000
};
#endif


namespace dart {
namespace bin {

union FSEvent {
  struct {
    uint32_t exists;
    uint32_t flags;
    char path[PATH_MAX];
  } data;
  uint8_t bytes[PATH_MAX + 8];
};

class FSEventsWatcher {
 public:
  class Node {
   public:
    Node(FSEventsWatcher* watcher, char* base_path, int read_fd,
         int write_fd, bool recursive)
        : watcher_(watcher),
          ready_(false),
          base_path_length_(strlen(base_path)),
          path_ref_(CFStringCreateWithCString(
              NULL, base_path, kCFStringEncodingUTF8)),
          read_fd_(read_fd),
          write_fd_(write_fd),
          recursive_(recursive),
          ref_(NULL) {
      Start();
    }

    ~Node() {
      Stop();
      VOID_TEMP_FAILURE_RETRY(close(write_fd_));
      CFRelease(path_ref_);
    }

    void set_ref(FSEventStreamRef ref) {
      ref_ = ref;
    }

    void Start() {
      // Schedule StartCallback to be executed in the RunLoop.
      CFRunLoopTimerContext context;
      memset(&context, 0, sizeof(context));
      context.info = this;
      CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
          NULL, 0, 0, 0, 0, Node::StartCallback, &context);
      CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes);
      CFRelease(timer);
      watcher_->monitor_.Enter();
      while (!ready_) {
        watcher_->monitor_.Wait(Monitor::kNoTimeout);
      }
      watcher_->monitor_.Exit();
    }

    static void StartCallback(CFRunLoopTimerRef timer, void* info) {
      Node* node = reinterpret_cast<Node*>(info);
      ASSERT(Thread::Compare(node->watcher_->threadId_,
                             Thread::GetCurrentThreadId()));
      FSEventStreamContext context;
      memset(&context, 0, sizeof(context));
      context.info = reinterpret_cast<void*>(node);
      CFArrayRef array = CFArrayCreate(
          NULL, reinterpret_cast<const void**>(&node->path_ref_), 1, NULL);
      FSEventStreamRef ref = FSEventStreamCreate(
          NULL,
          Callback,
          &context,
          array,
          kFSEventStreamEventIdSinceNow,
          0.10,
          kFSEventStreamCreateFlagFileEvents);
      CFRelease(array);

      node->set_ref(ref);

      FSEventStreamScheduleWithRunLoop(
          node->ref_,
          node->watcher_->run_loop_,
          kCFRunLoopDefaultMode);

      FSEventStreamStart(node->ref_);
      FSEventStreamFlushSync(node->ref_);

      node->watcher_->monitor_.Enter();
      node->ready_ = true;
      node->watcher_->monitor_.Notify();
      node->watcher_->monitor_.Exit();
    }

    void Stop() {
      // Schedule StopCallback to be executed in the RunLoop.
      ASSERT(ready_);
      CFRunLoopTimerContext context;
      memset(&context, 0, sizeof(context));
      context.info = this;
      CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
          NULL, 0, 0, 0, 0, StopCallback, &context);
      CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes);
      CFRelease(timer);
      watcher_->monitor_.Enter();
      while (ready_) {
        watcher_->monitor_.Wait(Monitor::kNoTimeout);
      }
      watcher_->monitor_.Exit();
    }

    static void StopCallback(CFRunLoopTimerRef timer, void* info) {
      Node* node = reinterpret_cast<Node*>(info);
      ASSERT(Thread::Compare(node->watcher_->threadId_,
                             Thread::GetCurrentThreadId()));
      FSEventStreamStop(node->ref_);
      FSEventStreamInvalidate(node->ref_);
      FSEventStreamRelease(node->ref_);
      node->watcher_->monitor_.Enter();
      node->ready_ = false;
      node->watcher_->monitor_.Notify();
      node->watcher_->monitor_.Exit();
    }

    FSEventsWatcher* watcher() const { return watcher_; }
    bool ready() const { return ready_; }
    intptr_t base_path_length() const { return base_path_length_; }
    int read_fd() const { return read_fd_; }
    int write_fd() const { return write_fd_; }
    bool recursive() const { return recursive_; }

   private:
    FSEventsWatcher* watcher_;
    bool ready_;
    intptr_t base_path_length_;
    CFStringRef path_ref_;
    int read_fd_;
    int write_fd_;
    bool recursive_;
    FSEventStreamRef ref_;
  };


  FSEventsWatcher() : run_loop_(0) {
    Start();
  }

  void Start() {
    Thread::Start(Run, reinterpret_cast<uword>(this));
    monitor_.Enter();
    while (run_loop_ == NULL) {
      monitor_.Wait(Monitor::kNoTimeout);
    }
    monitor_.Exit();
  }

  static void Run(uword arg) {
    FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(arg);
    // Only checked in debug mode.
    watcher->threadId_ = Thread::GetCurrentThreadId();
    watcher->run_loop_ = CFRunLoopGetCurrent();
    CFRetain(watcher->run_loop_);

    // Notify, as the run-loop is set.
    watcher->monitor().Enter();
    watcher->monitor().Notify();
    watcher->monitor().Exit();

    CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
        NULL,
        CFAbsoluteTimeGetCurrent() + 1,
        1,
        0,
        0,
        TimerCallback,
        NULL);
    CFRunLoopAddTimer(watcher->run_loop_, timer, kCFRunLoopCommonModes);
    CFRelease(timer);

    CFRunLoopRun();

    CFRelease(watcher->run_loop_);
    watcher->monitor_.Enter();
    watcher->run_loop_ = NULL;
    watcher->monitor_.Notify();
    watcher->monitor_.Exit();
  }

  void Stop() {
    // Schedule StopCallback to be executed in the RunLoop.
    CFRunLoopTimerContext context;
    memset(&context, 0, sizeof(context));
    context.info = this;
    CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
        NULL, 0, 0, 0, 0, StopCallback, &context);
    CFRunLoopAddTimer(run_loop_, timer, kCFRunLoopCommonModes);
    CFRelease(timer);
    monitor_.Enter();
    while (run_loop_ != NULL) {
      monitor_.Wait(Monitor::kNoTimeout);
    }
    monitor_.Exit();
  }

  static void StopCallback(CFRunLoopTimerRef timer, void* info) {
    FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(info);
    ASSERT(Thread::Compare(watcher->threadId_,
                           Thread::GetCurrentThreadId()));
    CFRunLoopStop(watcher->run_loop_);
  }

  ~FSEventsWatcher() {
    Stop();
  }

  Monitor& monitor() { return monitor_; }

  bool has_run_loop() const { return run_loop_ != NULL; }

  static void TimerCallback(CFRunLoopTimerRef timer, void* context) {
    // Dummy callback to keep RunLoop alive.
  }

  Node* AddPath(const char* path, int events, bool recursive) {
    int fds[2];
    VOID_NO_RETRY_EXPECTED(pipe(fds));
    Socket::SetNonBlocking(fds[0]);
    Socket::SetBlocking(fds[1]);

    char base_path[PATH_MAX];
    realpath(path, base_path);

    return new Node(this, base_path, fds[0], fds[1], recursive);
  }

 private:
  static void Callback(ConstFSEventStreamRef ref,
                       void* client,
                       size_t num_events,
                       void* event_paths,
                       const FSEventStreamEventFlags event_flags[],
                       const FSEventStreamEventId event_ids[]) {
    Node* node = reinterpret_cast<Node*>(client);
    ASSERT(Thread::Compare(node->watcher()->threadId_,
                           Thread::GetCurrentThreadId()));
    // `ready` is set on same thread as this callback is invoked, so we don't
    // need to lock here.
    if (!node->ready()) return;
    for (size_t i = 0; i < num_events; i++) {
      char *path = reinterpret_cast<char**>(event_paths)[i];
      FSEvent event;
      event.data.exists = File::GetType(path, false) != File::kDoesNotExist;
      path += node->base_path_length();
      // If path is longer the base, skip next character ('/').
      if (path[0] != '\0') path += 1;
      if (!node->recursive() && strstr(path, "/") != NULL) continue;
      event.data.flags = event_flags[i];
      memmove(event.data.path, path, strlen(path) + 1);
      write(node->write_fd(), event.bytes, sizeof(event));
    }
  }

  Monitor monitor_;
  CFRunLoopRef run_loop_;
  ThreadId threadId_;
};


#define kCFCoreFoundationVersionNumber10_7      635.00
bool FileSystemWatcher::IsSupported() {
  return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7;
}


intptr_t FileSystemWatcher::Init() {
  return reinterpret_cast<intptr_t>(new FSEventsWatcher());
}


void FileSystemWatcher::Close(intptr_t id) {
  delete reinterpret_cast<FSEventsWatcher*>(id);
}


intptr_t FileSystemWatcher::WatchPath(intptr_t id,
                                      const char* path,
                                      int events,
                                      bool recursive) {
  FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(id);
  return reinterpret_cast<intptr_t>(watcher->AddPath(path, events, recursive));
}


void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {
  USE(id);
  delete reinterpret_cast<FSEventsWatcher::Node*>(path_id);
}


intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) {
  return reinterpret_cast<FSEventsWatcher::Node*>(path_id)->read_fd();
}


Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
  intptr_t fd = GetSocketId(id, path_id);
  intptr_t avail = FDUtils::AvailableBytes(fd);
  int count = avail / sizeof(FSEvent);
  if (count <= 0) return Dart_NewList(0);
  Dart_Handle events = Dart_NewList(count);
  FSEvent e;
  for (int i = 0; i < count; i++) {
    intptr_t bytes = TEMP_FAILURE_RETRY(read(fd, e.bytes, sizeof(e)));
    if (bytes < 0) {
      return DartUtils::NewDartOSError();
    }
    size_t path_len = strlen(e.data.path);
    Dart_Handle event = Dart_NewList(5);
    int flags = e.data.flags;
    int mask = 0;
    if (flags & kFSEventStreamEventFlagItemRenamed) {
      if (path_len == 0) {
        // The moved path is the path being watched.
        mask |= kDeleteSelf;
      } else {
        mask |= e.data.exists ? kCreate : kDelete;
      }
    }
    if (flags & kFSEventStreamEventFlagItemModified) mask |= kModifyContent;
    if (flags & kFSEventStreamEventFlagItemXattrMod) mask |= kModefyAttribute;
    if (flags & kFSEventStreamEventFlagItemCreated) mask |= kCreate;
    if (flags & kFSEventStreamEventFlagItemIsDir) mask |= kIsDir;
    if (flags & kFSEventStreamEventFlagItemRemoved) {
      if (path_len == 0) {
        // The removed path is the path being watched.
        mask |= kDeleteSelf;
      } else {
        mask |= kDelete;
      }
    }
    Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
    Dart_ListSetAt(event, 1, Dart_NewInteger(1));
    Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8(
        reinterpret_cast<uint8_t*>(e.data.path), path_len));
    Dart_ListSetAt(event, 3, Dart_NewBoolean(true));
    Dart_ListSetAt(event, 4, Dart_NewInteger(path_id));
    Dart_ListSetAt(events, i, event);
  }
  return events;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(TARGET_OS_MACOS)


