// Copyright (c) 2010 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 "gobi-cromo-plugin/device_watcher.h"

extern "C" {
#include <libudev.h>
}

#include <base/logging.h>

static gboolean udev_event(GIOChannel* channel,
                           GIOCondition condition,
                           gpointer user_data) {
  DeviceWatcher* dw = static_cast<DeviceWatcher*>(user_data);
  dw->HandleUdevEvent();
  return TRUE;
}

static gboolean timeout_event(gpointer data) {
  DeviceWatcher* dw = static_cast<DeviceWatcher*>(data);
  dw->HandlePollEvent();
  return TRUE;
}

DeviceWatcher::DeviceWatcher(const char* subsystem)
  : subsystem_(subsystem),
    device_callback_(nullptr),
    timeout_callback_(nullptr),
    udev_(nullptr),
    udev_monitor_(nullptr),
    udev_watch_id_(0),
    timeout_id_(0) {
}

DeviceWatcher::~DeviceWatcher() {
  StopMonitoring();
}

void DeviceWatcher::StartMonitoring() {
  if (udev_) {
    LOG(WARNING) << "StartMonitoring called with monitoring already in effect";
    return;
  }
  udev_ = udev_new();
  if (!udev_) {
    LOG(WARNING) << "Failed to create udev context";
    return;
  }
  udev_monitor_ = udev_monitor_new_from_netlink(udev_, "udev");
  if (!udev_monitor_) {
    LOG(WARNING) << "Failed to create udev monitor";
    udev_unref(udev_);
    udev_ = nullptr;
    return;
  }
  int rc = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor_,
                                                           subsystem_.c_str(),
                                                           nullptr);
  if (rc != 0) {
    LOG(WARNING) << "Failed to add udev_monitor subsystem filter: " << rc;
    udev_monitor_unref(udev_monitor_);
    udev_unref(udev_);
    udev_ = nullptr;
    udev_monitor_ = nullptr;
  }
  rc = udev_monitor_enable_receiving(udev_monitor_);
  if (rc != 0) {
    LOG(WARNING) << "Failed to start udev monitoring: " << rc;
    udev_monitor_unref(udev_monitor_);
    udev_unref(udev_);
    udev_ = nullptr;
    udev_monitor_ = nullptr;
  }
  int fd = udev_monitor_get_fd(udev_monitor_);

  GIOChannel* iochan = g_io_channel_unix_new(fd);
  GError *gerror = nullptr;
  g_io_channel_set_encoding(iochan, nullptr, &gerror);
  g_io_channel_set_buffered(iochan, FALSE);
  udev_watch_id_ = g_io_add_watch(iochan, G_IO_IN, udev_event, this);
  g_io_channel_unref(iochan);
}

void DeviceWatcher::StopMonitoring() {
  if (udev_watch_id_ != 0) {
    g_source_remove(udev_watch_id_);
    udev_watch_id_ = 0;
  }
  if (udev_monitor_) {
    udev_monitor_filter_remove(udev_monitor_);
    udev_monitor_unref(udev_monitor_);
    udev_monitor_ = nullptr;
  }
  if (udev_) {
    udev_unref(udev_);
    udev_ = nullptr;
  }
}

void DeviceWatcher::StartPolling(int interval_secs,
                                 TimeoutCallback callback,
                                 void* userdata) {
  LOG(INFO) << "StartPolling(" << interval_secs << ")";
  timeout_callback_ = callback;
  timeout_callback_arg_ = userdata;
  timeout_id_ = g_timeout_add_seconds(interval_secs,
                                      timeout_event,
                                      this);
}

void DeviceWatcher::StopPolling() {
  if (timeout_id_ != 0) {
    LOG(INFO) << "StopPolling()";
    g_source_remove(timeout_id_);
    timeout_id_ = 0;
  }
}

static const char *NullFilter(const char *p) {
  return p ? p : "";
}

void DeviceWatcher::HandleUdevEvent() {
  struct udev_device* device = udev_monitor_receive_device(udev_monitor_);

  if (!device) {
    LOG(WARNING) << "No device from receive_device";
    return;
  }
  LOG(INFO) << "udev: "
            << "  Action: " << NullFilter(udev_device_get_action(device))
            << "  Node: " << NullFilter(udev_device_get_devnode(device))
            << "  Subsystem: " << NullFilter(udev_device_get_subsystem(device))
            << "  Devtype: " << NullFilter(udev_device_get_devtype(device))
            << "  Driver: " << NullFilter(udev_device_get_driver(device));
  if (device_callback_) {
    device_callback_(device_callback_arg_,
                     udev_device_get_action(device),
                     udev_device_get_devnode(device));
  }
  udev_device_unref(device);
}

void DeviceWatcher::HandlePollEvent() {
  if (timeout_callback_)
    timeout_callback_(timeout_callback_arg_);
}

void DeviceWatcher::set_callback(DeviceCallback callback, void* userdata) {
  device_callback_ = callback;
  device_callback_arg_ = userdata;
}
