// Copyright (c) 2011 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 SHILL_PROPERTY_ACCESSOR_
#define SHILL_PROPERTY_ACCESSOR_

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

#include "shill/accessor_interface.h"

namespace shill {

// Templated implementations of AccessorInterface<>.
// PropertyAccessor<> and ConstPropertyAccessor<> respectively provide
// R/W and R/O access to the value pointed to by |property|.
// this allows a class to easily map strings to member variables, so that
// pieces of state stored in the class can be queried or updated by name.
//
//   bool foo = true;
//   map<string, BoolAccessor> accessors;
//   accessors["foo"] = BoolAccessor(new PropertyAccessor<bool>(&foo));
//   bool new_foo = accessors["foo"]->Get();  // new_foo == true
//   accessors["foo"]->Set(false);  // returns true, because setting is allowed.
//                                  // foo == false, new_foo == true
//   new_foo = accessors["foo"]->Get();  // new_foo == false
template <class T>
class PropertyAccessor : public AccessorInterface<T> {
 public:
  explicit PropertyAccessor(T *property) : property_(property) {
    DCHECK(property);
  }
  virtual ~PropertyAccessor() {}

  const T &Get() { return *property_; }
  bool Set(const T &value) {
    *property_ = value;
    return true;
  }

 private:
  T * const property_;
  DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
};

template <class T>
class ConstPropertyAccessor : public AccessorInterface<T> {
 public:
  explicit ConstPropertyAccessor(const T *property) : property_(property) {
    DCHECK(property);
  }
  virtual ~ConstPropertyAccessor() {}

  const T &Get() { return *property_; }
  bool Set(const T &value) { return false; }

 private:
  const T * const property_;
  DISALLOW_COPY_AND_ASSIGN(ConstPropertyAccessor);
};

// CustomAccessor<> allows custom getter and setter methods to be provided.
// Thus, if the state to be returned is to be derived on-demand, we can
// still fit it into the AccessorInterface<> framework.
template<class C, class T>
class CustomAccessor : public AccessorInterface<T> {
 public:
  // |target| is the object on which to call the methods |getter| and |setter|
  // |setter| is allowed to be NULL, in which case we will simply reject
  // attempts to set via the accessor.
  // It is an error to pass NULL for either of the other two arguments.
  CustomAccessor(C *target, T(C::*getter)(), bool(C::*setter)(const T&))
      : target_(target),
        getter_(getter),
        setter_(setter) {
    DCHECK(target);
    DCHECK(getter);
  }
  virtual ~CustomAccessor() {}

  const T &Get() { return storage_ = (target_->*getter_)(); }
  bool Set(const T &value) { return setter_ && (target_->*setter_)(value); }

 private:
  C * const target_;
  // Get() returns a const&, so we need to have internal storage to which to
  // return a reference.
  T storage_;
  T(C::*getter_)(void);
  bool(C::*setter_)(const T&);
  DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
};

}  // namespace shill

#endif  // SHILL_PROPERTY_ACCESSOR_
