// 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(HOST_OS_MACOS)

#include "bin/file_system_watcher.h"

#if !HOST_OS_IOS

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

#include "bin/eventhandler.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/namespace.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();
      close(write_fd_);
      CFRelease(path_ref_);
    }

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

    void Start() {
      FSEventStreamContext context;
      memset(&context, 0, sizeof(context));
      context.info = reinterpret_cast<void*>(this);
      CFArrayRef array = CFArrayCreate(
          NULL, reinterpret_cast<const void**>(&path_ref_), 1, NULL);
      FSEventStreamRef ref = FSEventStreamCreate(
          NULL, Callback, &context, array, kFSEventStreamEventIdSinceNow, 0.10,
          kFSEventStreamCreateFlagFileEvents);
      CFRelease(array);

      set_ref(ref);
      ready_.store(true, std::memory_order_release);

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

      FSEventStreamStart(ref_);
      FSEventStreamFlushSync(ref_);
    }

    void Stop() {
      ASSERT(ready_);
      FSEventStreamStop(ref_);
      FSEventStreamInvalidate(ref_);
      FSEventStreamRelease(ref_);
      ready_.store(false, std::memory_order_release);
    }

    FSEventsWatcher* watcher() const { return watcher_; }
    bool ready() const { return ready_.load(std::memory_order_acquire); }
    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_;
    std::atomic<bool> ready_;
    intptr_t base_path_length_;
    CFStringRef path_ref_;
    int read_fd_;
    int write_fd_;
    bool recursive_;
    FSEventStreamRef ref_;

    DISALLOW_COPY_AND_ASSIGN(Node);
  };

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

  void Start() {
    Thread::Start("dart:io FileWatcher", 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));
    FDUtils::SetNonBlocking(fds[0]);
    FDUtils::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()));
    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(NULL, 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_;

  DISALLOW_COPY_AND_ASSIGN(FSEventsWatcher);
};

#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,
                                      Namespace* namespc,
                                      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) != 0) {
      if (path_len == 0) {
        // The moved path is the path being watched.
        mask |= kDeleteSelf;
      } else {
        mask |= e.data.exists ? kCreate : kDelete;
      }
    }
    if ((flags & kFSEventStreamEventFlagItemModified) != 0) {
      mask |= kModifyContent;
    }
    if ((flags & kFSEventStreamEventFlagItemXattrMod) != 0) {
      mask |= kModifyAttribute;
    }
    if ((flags & kFSEventStreamEventFlagItemCreated) != 0) {
      mask |= kCreate;
    }
    if ((flags & kFSEventStreamEventFlagItemIsDir) != 0) {
      mask |= kIsDir;
    }
    if ((flags & kFSEventStreamEventFlagItemRemoved) != 0) {
      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_Handle name = Dart_NewStringFromUTF8(
        reinterpret_cast<uint8_t*>(e.data.path), path_len);
    if (Dart_IsError(name)) {
      return name;
    }
    Dart_ListSetAt(event, 2, name);
    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

#else  // !HOST_OS_IOS

namespace dart {
namespace bin {

// FSEvents are unavailable on iOS. Stub out related methods
Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
  return DartUtils::NewDartOSError();
}

intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) {
  return -1;
}

bool FileSystemWatcher::IsSupported() {
  return false;
}

void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {}

intptr_t FileSystemWatcher::Init() {
  return -1;
}

void FileSystemWatcher::Close(intptr_t id) {}

intptr_t FileSystemWatcher::WatchPath(intptr_t id,
                                      Namespace* namespc,
                                      const char* path,
                                      int events,
                                      bool recursive) {
  return -1;
}

}  // namespace bin
}  // namespace dart

#endif  // !HOST_OS_IOS
#endif  // defined(HOST_OS_MACOS)
