// Copyright (c) 2009 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 LIBBRILLO_BRILLO_GLIB_OBJECT_H_
#define LIBBRILLO_BRILLO_GLIB_OBJECT_H_

#include <glib-object.h>
#include <stdint.h>

#include <algorithm>
#include <cstddef>
#include <memory>
#include <string>
#include <utility>

#include <base/logging.h>
#include <base/macros.h>

namespace brillo {

namespace details {  // NOLINT

// \brief ResetHelper is a private class for use with Resetter().
//
// ResetHelper passes ownership of a pointer to a scoped pointer type with reset
// on destruction.

template <typename T>  // T models ScopedPtr
class ResetHelper {
 public:
  typedef typename T::element_type element_type;

  explicit ResetHelper(T* x) : ptr_(nullptr), scoped_(x) {}
  ~ResetHelper() { scoped_->reset(ptr_); }
  element_type*& lvalue() { return ptr_; }

 private:
  element_type* ptr_;
  T* scoped_;
};

}  // namespace details

// \brief Resetter() is a utility function for passing pointers to
//  scoped pointers.
//
// The Resetter() function return a temporary object containing an lvalue of
// \code T::element_type which can be assigned to. When the temporary object
// destructs, the associated scoped pointer is reset with the lvalue. It is of
// general use when a pointer is returned as an out-argument.
//
// \example
// void function(int** x) {
//   *x = new int(10);
// }
// ...
// std::unique_ptr<int> x;
// function(Resetter(x).lvalue());
//
// \end_example

template <typename T>  // T models ScopedPtr
details::ResetHelper<T> Resetter(T* x) {
  return details::ResetHelper<T>(x);
}

namespace glib {

// \brief type_to_gtypeid is a type function mapping from a canonical type to
// the GType typeid for the associated GType (see type_to_gtype).

template <typename T>
::GType type_to_gtypeid();

template <>
inline ::GType type_to_gtypeid<const char*>() {
  return G_TYPE_STRING;
}
template <>
inline ::GType type_to_gtypeid<char*>() {
  return G_TYPE_STRING;
}
template <>
inline ::GType type_to_gtypeid< ::uint8_t>() {
  return G_TYPE_UCHAR;
}
template <>
inline ::GType type_to_gtypeid<double>() {
  return G_TYPE_DOUBLE;
}
template <>
inline ::GType type_to_gtypeid<bool>() {
  return G_TYPE_BOOLEAN;
}
class Value;
template <>
inline ::GType type_to_gtypeid<const Value*>() {
  return G_TYPE_VALUE;
}

template <>
inline ::GType type_to_gtypeid< ::uint32_t>() {
  // REVISIT (seanparent) : There currently isn't any G_TYPE_UINT32, this code
  // assumes sizeof(guint) == sizeof(guint32). Need a static_assert to assert
  // that.
  return G_TYPE_UINT;
}

template <>
inline ::GType type_to_gtypeid< ::int64_t>() {
  return G_TYPE_INT64;
}

template <>
inline ::GType type_to_gtypeid< ::int32_t>() {
  return G_TYPE_INT;
}

// \brief Value (and Retrieve) support using std::string as well as const char*
// by promoting from const char* to the string. promote_from provides a mapping
// for this promotion (and possibly others in the future).

template <typename T>
struct promotes_from {
  typedef T type;
};
template <>
struct promotes_from<std::string> {
  typedef const char* type;
};

// \brief RawCast converts from a GValue to a value of a canonical type.
//
// RawCast is a low level function. Generally, use Cast() instead.
//
// \precondition \param x contains a value of type \param T.

template <typename T>
inline T RawCast(const ::GValue& x) {
  // Use static_assert() to issue a meaningful compile-time error.
  // To prevent this from happening for all references to RawCast, use sizeof(T)
  // to make static_assert depend on type T and therefore prevent binding it
  // unconditionally until the actual RawCast<T> instantiation happens.
  static_assert(sizeof(T) == 0, "Using RawCast on unsupported type");
  return T();
}

template <>
inline const char* RawCast<const char*>(const ::GValue& x) {
  return static_cast<const char*>(::g_value_get_string(&x));
}
template <>
inline double RawCast<double>(const ::GValue& x) {
  return static_cast<double>(::g_value_get_double(&x));
}
template <>
inline bool RawCast<bool>(const ::GValue& x) {
  return static_cast<bool>(::g_value_get_boolean(&x));
}
template <>
inline ::uint32_t RawCast< ::uint32_t>(const ::GValue& x) {
  return static_cast< ::uint32_t>(::g_value_get_uint(&x));
}
template <>
inline ::uint8_t RawCast< ::uint8_t>(const ::GValue& x) {
  return static_cast< ::uint8_t>(::g_value_get_uchar(&x));
}
template <>
inline ::int64_t RawCast< ::int64_t>(const ::GValue& x) {
  return static_cast< ::int64_t>(::g_value_get_int64(&x));
}
template <>
inline ::int32_t RawCast< ::int32_t>(const ::GValue& x) {
  return static_cast< ::int32_t>(::g_value_get_int(&x));
}

inline void RawSet(GValue* x, const std::string& v) {
  ::g_value_set_string(x, v.c_str());
}
inline void RawSet(GValue* x, const char* v) {
  ::g_value_set_string(x, v);
}
inline void RawSet(GValue* x, double v) {
  ::g_value_set_double(x, v);
}
inline void RawSet(GValue* x, bool v) {
  ::g_value_set_boolean(x, v);
}
inline void RawSet(GValue* x, ::uint32_t v) {
  ::g_value_set_uint(x, v);
}
inline void RawSet(GValue* x, ::uint8_t v) {
  ::g_value_set_uchar(x, v);
}
inline void RawSet(GValue* x, ::int64_t v) {
  ::g_value_set_int64(x, v);
}
inline void RawSet(GValue* x, ::int32_t v) {
  ::g_value_set_int(x, v);
}

// \brief Value is a data type for managing GValues.
//
// A Value is a polymorphic container holding at most a single value.
//
// The Value wrapper ensures proper initialization, copies, and assignment of
// GValues.
//
// \note GValues are equationally incomplete and so can't support proper
// equality. The semantics of copy are verified with equality of retrieved
// values.

class Value : public ::GValue {
 public:
  Value() : GValue() {}
  explicit Value(const ::GValue& x) : GValue() {
    *this = *static_cast<const Value*>(&x);
  }
  template <typename T>
  explicit Value(T x) : GValue() {
    ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>());
    RawSet(this, x);
  }
  Value(const Value& x) : GValue() {
    if (x.empty())
      return;
    ::g_value_init(this, G_VALUE_TYPE(&x));
    ::g_value_copy(&x, this);
  }
  ~Value() { clear(); }
  Value& operator=(const Value& x) {
    if (this == &x)
      return *this;
    clear();
    if (x.empty())
      return *this;
    ::g_value_init(this, G_VALUE_TYPE(&x));
    ::g_value_copy(&x, this);
    return *this;
  }
  template <typename T>
  Value& operator=(const T& x) {
    clear();
    ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>());
    RawSet(this, x);
    return *this;
  }

  // Lower-case names to follow STL container conventions.

  void clear() {
    if (!empty())
      ::g_value_unset(this);
  }

  bool empty() const { return G_VALUE_TYPE(this) == G_TYPE_INVALID; }
};

template <>
inline const Value* RawCast<const Value*>(const ::GValue& x) {
  return static_cast<const Value*>(&x);
}

// \brief Retrieve gets a value from a GValue.
//
// \postcondition If \param x contains a value of type \param T, then the
//  value is copied to \param result and \true is returned. Otherwise, \param
//  result is unchanged and \false is returned.
//
// \precondition \param result is not \nullptr.

template <typename T>
bool Retrieve(const ::GValue& x, T* result) {
  if (!G_VALUE_HOLDS(&x, type_to_gtypeid<typename promotes_from<T>::type>())) {
    LOG(WARNING) << "GValue retrieve failed. Expected: "
                 << g_type_name(
                        type_to_gtypeid<typename promotes_from<T>::type>())
                 << ", Found: " << g_type_name(G_VALUE_TYPE(&x));
    return false;
  }

  *result = RawCast<typename promotes_from<T>::type>(x);
  return true;
}

inline bool Retrieve(const ::GValue& x, Value* result) {
  *result = Value(x);
  return true;
}

// \brief ScopedError holds a ::GError* and deletes it on destruction.

struct FreeError {
  void operator()(::GError* x) const {
    if (x)
      ::g_error_free(x);
  }
};

typedef std::unique_ptr< ::GError, FreeError> ScopedError;

// \brief ScopedArray holds a ::GArray* and deletes both the container and the
// segment containing the elements on destruction.

struct FreeArray {
  void operator()(::GArray* x) const {
    if (x)
      ::g_array_free(x, TRUE);
  }
};

typedef std::unique_ptr< ::GArray, FreeArray> ScopedArray;

// \brief ScopedPtrArray adapts ::GPtrArray* to conform to the standard
//  container requirements.
//
// \note ScopedPtrArray is only partially implemented and is being fleshed out
//  as needed.
//
// \models Random Access Container, Back Insertion Sequence, ScopedPtrArray is
//  not copyable and equationally incomplete.

template <typename T>  // T models pointer
class ScopedPtrArray {
 public:
  typedef ::GPtrArray element_type;

  typedef T value_type;
  typedef const value_type& const_reference;
  typedef value_type* iterator;
  typedef const value_type* const_iterator;

  ScopedPtrArray() : object_(0) {}

  explicit ScopedPtrArray(::GPtrArray* x) : object_(x) {}
  ScopedPtrArray(const ScopedPtrArray&) = delete;
  ScopedPtrArray& operator=(const ScopedPtrArray&) = delete;

  ~ScopedPtrArray() { clear(); }

  iterator begin() { return iterator(object_ ? object_->pdata : nullptr); }
  iterator end() { return begin() + size(); }
  const_iterator begin() const {
    return const_iterator(object_ ? object_->pdata : nullptr);
  }
  const_iterator end() const { return begin() + size(); }

  // \precondition x is a pointer to an object allocated with g_new().

  void push_back(T x) {
    if (!object_)
      object_ = ::g_ptr_array_sized_new(1);
    ::g_ptr_array_add(object_, ::gpointer(x));
  }

  T& operator[](std::size_t n) {
    DCHECK(!(size() < n)) << "ScopedPtrArray index out-of-bound.";
    return *(begin() + n);
  }

  std::size_t size() const { return object_ ? object_->len : 0; }

  void clear() {
    if (object_) {
      std::for_each(begin(), end(), FreeHelper());
      ::g_ptr_array_free(object_, true);
      object_ = nullptr;
    }
  }

  void reset(::GPtrArray* p = nullptr) {
    if (p != object_) {
      clear();
      object_ = p;
    }
  }

 private:
  struct FreeHelper {
    void operator()(T x) const { ::g_free(::gpointer(x)); }
  };

  template <typename U>
  friend void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y);

  ::GPtrArray* object_;
};

template <typename U>
inline void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y) {
  std::swap(x.object_, y.object_);
}

// \brief ScopedHashTable manages the lifetime of a ::GHashTable* with an
// interface compatibitle with a scoped ptr.
//
// The ScopedHashTable is also the start of an adaptor to model a standard
// Container. The standard for an associative container would have an iterator
// returning a key value pair. However, that isn't possible with
// ::GHashTable because there is no interface returning a reference to the
// key value pair, only to retrieve the keys and values and individual elements.
//
// So the standard interface of find() wouldn't work. I considered implementing
// operator[] and count() - operator []. So retrieving a value would look like:
//
// if (table.count(key))
//   success = Retrieve(table[key], &value);
//
// But that requires hashing the key twice.
// For now I implemented a Retrieve member function to follow the pattern
// developed elsewhere in the code.
//
// bool success = Retrieve(key, &x);
//
// This is also a template to retrieve the corect type from the stored GValue
// type.
//
// I may revisit this and use scoped_ptr_malloc and a non-member function
// Retrieve() in the future. The Retrieve pattern is becoming common enough
// that I want to give some thought as to how to generalize it further.

class ScopedHashTable {
 public:
  typedef ::GHashTable element_type;

  ScopedHashTable() : object_(nullptr) {}

  explicit ScopedHashTable(::GHashTable* p) : object_(p) {}

  ~ScopedHashTable() { clear(); }

  template <typename T>
  bool Retrieve(const char* key, T* result) const {
    DCHECK(object_) << "Retrieve on empty ScopedHashTable.";
    if (!object_)
      return false;

    ::gpointer ptr = ::g_hash_table_lookup(object_, key);
    if (!ptr)
      return false;
    return glib::Retrieve(*static_cast< ::GValue*>(ptr), result);
  }

  void clear() {
    if (object_) {
      ::g_hash_table_unref(object_);
      object_ = nullptr;
    }
  }

  GHashTable* get() { return object_; }

  void reset(::GHashTable* p = nullptr) {
    if (p != object_) {
      clear();
      object_ = p;
    }
  }

 private:
  ::GHashTable* object_;
};

}  // namespace glib
}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_GLIB_OBJECT_H_
