// 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_LINUX)

#include "bin/file_system_watcher.h"

#include <errno.h>        // NOLINT
#include <sys/inotify.h>  // NOLINT

#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/socket.h"
#include "platform/signal_blocker.h"

namespace dart {
namespace bin {

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

intptr_t FileSystemWatcher::Init() {
  int id = NO_RETRY_EXPECTED(inotify_init1(IN_CLOEXEC));
  if (id < 0) {
    return -1;
  }
  // Some systems dosn't support setting this as non-blocking. Since watching
  // internals are kept away from the user, we know it's possible to continue,
  // even if setting non-blocking fails.
  FDUtils::SetNonBlocking(id);
  return id;
}

void FileSystemWatcher::Close(intptr_t id) {
  USE(id);
}

intptr_t FileSystemWatcher::WatchPath(intptr_t id,
                                      Namespace* namespc,
                                      const char* path,
                                      int events,
                                      bool recursive) {
  int list_events = IN_DELETE_SELF | IN_MOVE_SELF;
  if ((events & kCreate) != 0) {
    list_events |= IN_CREATE;
  }
  if ((events & kModifyContent) != 0) {
    list_events |= IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY;
  }
  if ((events & kDelete) != 0) {
    list_events |= IN_DELETE;
  }
  if ((events & kMove) != 0) {
    list_events |= IN_MOVE;
  }
  const char* resolved_path = File::GetCanonicalPath(namespc, path);
  path = resolved_path != NULL ? resolved_path : path;
  int path_id = NO_RETRY_EXPECTED(inotify_add_watch(id, path, list_events));
  if (path_id < 0) {
    return -1;
  }
  return path_id;
}

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

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

static int InotifyEventToMask(struct inotify_event* e) {
  int mask = 0;
  if ((e->mask & IN_CLOSE_WRITE) != 0 || (e->mask & IN_MODIFY) != 0) {
    mask |= FileSystemWatcher::kModifyContent;
  }
  if ((e->mask & IN_ATTRIB) != 0) {
    mask |= FileSystemWatcher::kModifyAttribute;
  }
  if ((e->mask & IN_CREATE) != 0) {
    mask |= FileSystemWatcher::kCreate;
  }
  if ((e->mask & IN_MOVE) != 0) {
    mask |= FileSystemWatcher::kMove;
  }
  if ((e->mask & IN_DELETE) != 0) {
    mask |= FileSystemWatcher::kDelete;
  }
  if ((e->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) != 0) {
    mask |= FileSystemWatcher::kDeleteSelf;
  }
  if ((e->mask & IN_ISDIR) != 0) {
    mask |= FileSystemWatcher::kIsDir;
  }
  return mask;
}

Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
  USE(path_id);
  const intptr_t kEventSize = sizeof(struct inotify_event);
  const intptr_t kBufferSize = kEventSize + NAME_MAX + 1;
  uint8_t buffer[kBufferSize];
  intptr_t bytes =
      SocketBase::Read(id, buffer, kBufferSize, SocketBase::kAsync);
  if (bytes < 0) {
    return DartUtils::NewDartOSError();
  }
  const intptr_t kMaxCount = bytes / kEventSize;
  Dart_Handle events = Dart_NewList(kMaxCount);
  intptr_t offset = 0;
  intptr_t i = 0;
  while (offset < bytes) {
    struct inotify_event* e =
        reinterpret_cast<struct inotify_event*>(buffer + offset);
    if ((e->mask & IN_IGNORED) == 0) {
      Dart_Handle event = Dart_NewList(5);
      int mask = InotifyEventToMask(e);
      Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
      Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
      if (e->len > 0) {
        Dart_Handle name = Dart_NewStringFromUTF8(
            reinterpret_cast<uint8_t*>(e->name), strlen(e->name));
        if (Dart_IsError(name)) {
          return name;
        }
        Dart_ListSetAt(event, 2, name);
      } else {
        Dart_ListSetAt(event, 2, Dart_Null());
      }
      Dart_ListSetAt(event, 3, Dart_NewBoolean((e->mask & IN_MOVED_TO) != 0u));
      Dart_ListSetAt(event, 4, Dart_NewInteger(e->wd));
      Dart_ListSetAt(events, i, event);
      i++;
    }
    offset += kEventSize + e->len;
  }
  ASSERT(offset == bytes);
  return events;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(HOST_OS_LINUX)
