// 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) {
    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) {
    udev_enumerate_unref(udev_enum);
  }

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

}  // namespace chromeos_update_engine

#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_UDEV_INTERFACE_H_
