// 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 <base/logging.h>
#include <base/macros.h>

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

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);
}

// \precondition No functions in the glib namespace can be called before
// ::g_type_init();

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() {
    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_;

  DISALLOW_COPY_AND_ASSIGN(ScopedPtrArray);
};

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_
