// Copyright (c) 2013 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 "mist/udev_enumerate.h"

#include <libudev.h>

#include <base/logging.h>
#include <base/strings/stringprintf.h>

#include "mist/udev_device.h"

using base::StringPrintf;

namespace mist {

UdevEnumerate::UdevEnumerate() : enumerate_(nullptr) {}

UdevEnumerate::UdevEnumerate(udev_enumerate* enumerate)
    : enumerate_(enumerate) {
  CHECK(enumerate_);

  udev_enumerate_ref(enumerate_);
}

UdevEnumerate::~UdevEnumerate() {
  if (enumerate_) {
    udev_enumerate_unref(enumerate_);
    enumerate_ = nullptr;
  }
}

bool UdevEnumerate::AddMatchSubsystem(const char* subsystem) {
  int result = udev_enumerate_add_match_subsystem(enumerate_, subsystem);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_subsystem (%p, \"%s\") returned %d.",
      enumerate_, subsystem, result);
  return false;
}

bool UdevEnumerate::AddNoMatchSubsystem(const char* subsystem) {
  int result = udev_enumerate_add_nomatch_subsystem(enumerate_, subsystem);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_nomatch_subsystem (%p, \"%s\") returned %d.",
      enumerate_, subsystem, result);
  return false;
}

bool UdevEnumerate::AddMatchSysAttribute(const char* attribute,
                                         const char* value) {
  int result = udev_enumerate_add_match_sysattr(enumerate_, attribute, value);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_sysattr (%p, \"%s\", \"%s\") returned %d.",
      enumerate_, attribute, value, result);
  return false;
}

bool UdevEnumerate::AddNoMatchSysAttribute(const char* attribute,
                                           const char* value) {
  int result = udev_enumerate_add_nomatch_sysattr(enumerate_, attribute, value);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_nomatch_sysattr (%p, \"%s\", \"%s\") returned %d.",
      enumerate_, attribute, value, result);
  return false;
}

bool UdevEnumerate::AddMatchProperty(const char* property, const char* value) {
  int result = udev_enumerate_add_match_property(enumerate_, property, value);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_property (%p, \"%s\", \"%s\") returned %d.",
      enumerate_, property, value, result);
  return false;
}

bool UdevEnumerate::AddMatchSysName(const char* sys_name) {
  int result = udev_enumerate_add_match_sysname(enumerate_, sys_name);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_sysname (%p, \"%s\") returned %d.", enumerate_,
      sys_name, result);
  return false;
}

bool UdevEnumerate::AddMatchTag(const char* tag) {
  int result = udev_enumerate_add_match_tag(enumerate_, tag);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_tag (%p, \"%s\") returned %d.", enumerate_, tag,
      result);
  return false;
}

bool UdevEnumerate::AddMatchIsInitialized() {
  int result = udev_enumerate_add_match_is_initialized(enumerate_);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf(
      "udev_enumerate_add_match_is_initialized (%p) returned %d.", enumerate_,
      result);
  return false;
}

bool UdevEnumerate::AddSysPath(const char* sys_path) {
  int result = udev_enumerate_add_syspath(enumerate_, sys_path);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf("udev_enumerate_add_syspath(%p, \"%s\") returned %d.",
                          enumerate_, sys_path, result);
  return false;
}

bool UdevEnumerate::ScanDevices() {
  int result = udev_enumerate_scan_devices(enumerate_);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf("udev_enumerate_scan_devices(%p) returned %d.",
                          enumerate_, result);
  return false;
}

bool UdevEnumerate::ScanSubsystems() {
  int result = udev_enumerate_scan_subsystems(enumerate_);
  if (result == 0)
    return true;

  VLOG(2) << StringPrintf("udev_enumerate_scan_subsystems(%p) returned %d.",
                          enumerate_, result);
  return false;
}

UdevListEntry* UdevEnumerate::GetListEntry() const {
  udev_list_entry* list_entry = udev_enumerate_get_list_entry(enumerate_);
  return list_entry ? new UdevListEntry(list_entry) : nullptr;
}

}  // namespace mist
