// Copyright 2015 The Chromium OS 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 "permission_broker/rule_engine.h"

#include <libudev.h>
#include <poll.h>
#include <sys/inotify.h>

#include "base/logging.h"
#include "permission_broker/rule.h"

namespace permission_broker {

RuleEngine::RuleEngine()
    : udev_(udev_new()) {}

RuleEngine::RuleEngine(const std::string& udev_run_path,
                       const base::TimeDelta& poll_interval)
    : udev_(udev_new()),
      poll_interval_(poll_interval),
      udev_run_path_(udev_run_path) {
  CHECK(udev_) << "Could not create udev context, is sysfs mounted?";
}

RuleEngine::~RuleEngine() {
}

void RuleEngine::AddRule(Rule* rule) {
  CHECK(rule) << "Cannot add NULL as a rule.";
  rules_.push_back(std::unique_ptr<Rule>(rule));
}

Rule::Result RuleEngine::ProcessPath(const std::string& path) {
  WaitForEmptyUdevQueue();

  LOG(INFO) << "ProcessPath(" << path << ")";
  Rule::Result result = Rule::IGNORE;

  ScopedUdevDevicePtr device(FindUdevDevice(path));
  if (device.get()) {
    for (const std::unique_ptr<Rule>& rule : rules_) {
      Rule::Result rule_result = rule->ProcessDevice(device.get());
      LOG(INFO) << "  " << rule->name() << ": "
                << Rule::ResultToString(rule_result);
      if (rule_result == Rule::DENY) {
        result = Rule::DENY;
        break;
      } else if (rule_result == Rule::ALLOW_WITH_DETACH) {
        result = Rule::ALLOW_WITH_DETACH;
      } else if (rule_result == Rule::ALLOW_WITH_LOCKDOWN) {
        result = Rule::ALLOW_WITH_LOCKDOWN;
      } else if (rule_result == Rule::ALLOW &&
                 result != Rule::ALLOW_WITH_DETACH &&
                 result != Rule::ALLOW_WITH_LOCKDOWN) {
        result = Rule::ALLOW;
      }
    }
  } else {
    LOG(INFO) << "No udev entry found for " << path << ", denying access.";
    result = Rule::DENY;
  }

  LOG(INFO) << "Verdict for " << path << ": " << Rule::ResultToString(result);
  return result;
}

void RuleEngine::WaitForEmptyUdevQueue() {
  struct udev_queue* queue = udev_queue_new(udev_.get());
  if (udev_queue_get_queue_is_empty(queue)) {
    udev_queue_unref(queue);
    return;
  }

  struct pollfd udev_poll;
  memset(&udev_poll, 0, sizeof(udev_poll));
  udev_poll.fd = inotify_init();
  udev_poll.events = POLLIN;

  int watch =
      inotify_add_watch(udev_poll.fd, udev_run_path_.c_str(), IN_MOVED_TO);
  CHECK_NE(watch, -1) << "Could not add watch for udev run directory.";

  while (!udev_queue_get_queue_is_empty(queue)) {
    if (poll(&udev_poll, 1, poll_interval_.InMilliseconds()) > 0) {
      char buffer[sizeof(struct inotify_event)];
      const ssize_t result = read(udev_poll.fd, buffer, sizeof(buffer));
      if (result < 0)
        LOG(WARNING) << "Did not read complete udev event.";
    }
  }
  udev_queue_unref(queue);
  close(udev_poll.fd);
}

ScopedUdevDevicePtr RuleEngine::FindUdevDevice(const std::string& path) {
  ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev_.get()));
  udev_enumerate_scan_devices(enumerate.get());

  struct udev_list_entry* entry = nullptr;
  udev_list_entry_foreach(entry,
                          udev_enumerate_get_list_entry(enumerate.get())) {
    const char* syspath = udev_list_entry_get_name(entry);
    ScopedUdevDevicePtr device(
        udev_device_new_from_syspath(udev_.get(), syspath));

    const char* devnode = udev_device_get_devnode(device.get());
    if (devnode && !strcmp(devnode, path.c_str()))
      return device;
  }

  return nullptr;
}

}  // namespace permission_broker
