// Copyright (c) 2012 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.

#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_UDEV_INTERFACE_H__
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_UDEV_INTERFACE_H__

#include <libudev.h>

#include "update_engine/utils.h"

// An interface for libudev calls, allowing to easily mock it.

namespace chromeos_update_engine {

// An interface for libudev methods that are being used in update engine.
//
// TODO(garnold) As is, this is a pretty lame indirection layer that otherwise
// does not provide any better abstraction than the existing libudev API. Done
// properly, we should replace it with encapsulated udev, enumerate and device
// objects, and hide initialization, reference handling and iterators in ways
// more appropriate to an object-oriented setting...
class UdevInterface {
 public:
  virtual ~UdevInterface() {}

  // Interfaces for various udev closers. All of these are merely containers for
  // a single pointer to some udev handle, which invoke the provided interface's
  // unref method and nullify the handle upon destruction. It should suffice for
  // derivative (concrete) interfaces to implement the various unref methods to
  // fit their needs, making these closers behave as expected.
  class UdevCloser {
   public:
    explicit UdevCloser(UdevInterface* udev_iface, struct udev** udev_p)
        : udev_iface_(udev_iface), udev_p_(udev_p) {
      CHECK(udev_iface && udev_p);
    }
    virtual ~UdevCloser() {
      if (*udev_p_) {
        udev_iface_->Unref(*udev_p_);
        *udev_p_ = NULL;
      }
    }
   protected:
    UdevInterface* udev_iface_;
    struct udev** udev_p_;
   private:
    DISALLOW_IMPLICIT_CONSTRUCTORS(UdevCloser);
  };

  class UdevEnumerateCloser {
   public:
    explicit UdevEnumerateCloser(UdevInterface* udev_iface,
                                 struct udev_enumerate** udev_enum_p)
        : udev_iface_(udev_iface), udev_enum_p_(udev_enum_p) {
      CHECK(udev_iface && udev_enum_p);
    }
    virtual ~UdevEnumerateCloser() {
      if (*udev_enum_p_) {
        udev_iface_->EnumerateUnref(*udev_enum_p_);
        *udev_enum_p_ = NULL;
      }
    }
   protected:
    UdevInterface* udev_iface_;
    struct udev_enumerate** udev_enum_p_;
   private:
    DISALLOW_IMPLICIT_CONSTRUCTORS(UdevEnumerateCloser);
  };

  class UdevDeviceCloser {
   public:
    explicit UdevDeviceCloser(UdevInterface* udev_iface,
                              struct udev_device** udev_dev_p)
        : udev_iface_(udev_iface), udev_dev_p_(udev_dev_p) {
      CHECK(udev_iface && udev_dev_p);
    }
    virtual ~UdevDeviceCloser() {
      if (*udev_dev_p_) {
        udev_iface_->DeviceUnref(*udev_dev_p_);
        *udev_dev_p_ = NULL;
      }
    }
   protected:
    UdevInterface* udev_iface_;
    struct udev_device** udev_dev_p_;
   private:
    DISALLOW_IMPLICIT_CONSTRUCTORS(UdevDeviceCloser);
  };

  virtual UdevCloser* NewUdevCloser(struct udev** udev_p) {
    return new UdevCloser(this, udev_p);
  }
  virtual UdevEnumerateCloser* NewUdevEnumerateCloser(
      struct udev_enumerate** udev_enum_p) {
    return new UdevEnumerateCloser(this, udev_enum_p);
  }
  virtual UdevDeviceCloser* NewUdevDeviceCloser(
      struct udev_device** udev_dev_p) {
    return new UdevDeviceCloser(this, udev_dev_p);
  }

  // Lists.
  virtual const char* ListEntryGetName(struct udev_list_entry* list_entry) = 0;
  virtual udev_list_entry* ListEntryGetNext(
      struct udev_list_entry* list_entry) = 0;

  // Device methods.
  virtual struct udev_device* DeviceNewFromSyspath(
      struct udev* udev,
      const char* syspath) = 0;
  virtual const char* DeviceGetPropertyValue(struct udev_device* udev_device,
                                             const char* key) = 0;
  virtual const char* DeviceGetSyspath(
      struct udev_device* udev_device) = 0;
  virtual void DeviceUnref(struct udev_device* udev_device) = 0;

  // Enumerate methods.
  virtual struct udev_enumerate* EnumerateNew(struct udev* udev) = 0;
  virtual int EnumerateAddMatchSubsystem(struct udev_enumerate* udev_enum,
                                         const char* subsystem) = 0;
  virtual int EnumerateAddMatchSysname(struct udev_enumerate* udev_enum,
                                       const char* sysname) = 0;
  virtual int EnumerateScanDevices(struct udev_enumerate* udev_enum) = 0;
  virtual struct udev_list_entry* EnumerateGetListEntry(
      struct udev_enumerate* udev_enum) = 0;
  virtual void EnumerateUnref(struct udev_enumerate* udev_enum) = 0;

  // Udev instance methods.
  virtual struct udev* New() = 0;
  virtual void Unref(struct udev* udev) = 0;
};


// Implementation of libudev interface using concrete udev calls.
class StandardUdevInterface : public UdevInterface {
 public:
  virtual ~StandardUdevInterface() {}

  // Concrete udev API wrappers utilizing the standard libudev calls.
  virtual const char* ListEntryGetName(struct udev_list_entry* list_entry) {
    return udev_list_entry_get_name(list_entry);
  }
  virtual struct udev_list_entry* ListEntryGetNext(
      struct udev_list_entry* list_entry) {
    return udev_list_entry_get_next(list_entry);
  }

  virtual struct udev_device* DeviceNewFromSyspath(struct udev* udev,
                                                   const char* syspath) {
    return udev_device_new_from_syspath(udev, syspath);
  }
  virtual const char* DeviceGetPropertyValue(struct udev_device* udev_device,
                                             const char* key) {
    return udev_device_get_property_value(udev_device, key);
  }
  virtual const char* DeviceGetSyspath(struct udev_device* udev_device) {
    return udev_device_get_syspath(udev_device);
  }
  virtual void DeviceUnref(struct udev_device* udev_device) {
    return udev_device_unref(udev_device);
  }

  virtual struct udev_enumerate* EnumerateNew(struct udev* udev) {
    return udev_enumerate_new(udev);
  }
  virtual int EnumerateAddMatchSubsystem(struct udev_enumerate* udev_enum,
                                         const char* subsystem) {
    return udev_enumerate_add_match_subsystem(udev_enum, subsystem);
  }
  virtual int EnumerateAddMatchSysname(struct udev_enumerate* udev_enum,
                                       const char* sysname) {
    return udev_enumerate_add_match_sysname(udev_enum, sysname);
  }
  virtual int EnumerateScanDevices(struct udev_enumerate* udev_enum) {
    return udev_enumerate_scan_devices(udev_enum);
  }
  virtual struct udev_list_entry* EnumerateGetListEntry(
      struct udev_enumerate* udev_enum) {
    return udev_enumerate_get_list_entry(udev_enum);
  }
  virtual void EnumerateUnref(struct udev_enumerate* udev_enum) {
    return udev_enumerate_unref(udev_enum);
  }

  virtual struct udev* New() {
    return udev_new();
  }
  virtual void Unref(struct udev* udev) {
    return udev_unref(udev);
  }
};

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_UDEV_INTERFACE_H__

