// 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:
  // 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:
  // 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__

