// Copyright 2018 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_H_
#define SHILL_PROPERTY_ACCESSOR_H_

#include <base/macros.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST.

#include "shill/accessor_interface.h"
#include "shill/error.h"
#include "shill/logging.h"

namespace shill {

// Templated implementations of AccessorInterface<>.
//
// PropertyAccessor<>, ConstPropertyAccessor<>, and
// WriteOnlyPropertyAccessor<> provide R/W, R/O, and W/O access
// (respectively) 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"].reset(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
//   // Clear resets |foo| to its value when the PropertyAccessor was created.
//   accessors["foo"]->Clear();  // foo == true
//
// Generic accessors that provide write capability will check that the
// new value differs from the present one. If the old and new values
// are the same, the setter will not invoke the assignment operator, and
// will return false.
//
// Custom accessors are responsible for handling set-to-same-value
// themselves. It is not possible to handle that here, because some
// custom getters return default values, rather than the actual
// value. (I'm looking at you, WiFi::GetBgscanMethod.)
template <class T>
class PropertyAccessor : public AccessorInterface<T> {
 public:
  explicit PropertyAccessor(T* property)
      : property_(property), default_value_(*property) {
    DCHECK(property);
  }
  ~PropertyAccessor() override = default;

  void Clear(Error* error) override { Set(default_value_, error); }
  T Get(Error* /*error*/) override { return *property_; }
  bool Set(const T& value, Error* /*error*/) override {
    if (*property_ == value) {
      return false;
    }
    *property_ = value;
    return true;
  }

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

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

  void Clear(Error* error) override {
    // TODO(quiche): check if this is the right error.
    // (maybe Error::kInvalidProperty instead?)
    error->Populate(Error::kInvalidArguments, "Property is read-only");
  }
  T Get(Error* /*error*/) override { return *property_; }
  bool Set(const T& /*value*/, Error* error) override {
    // TODO(quiche): check if this is the right error.
    // (maybe Error::kPermissionDenied instead?)
    error->Populate(Error::kInvalidArguments, "Property is read-only");
    return false;
  }

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

template <class T>
class WriteOnlyPropertyAccessor : public AccessorInterface<T> {
 public:
  explicit WriteOnlyPropertyAccessor(T* property)
      : property_(property), default_value_(*property) {
    DCHECK(property);
  }
  ~WriteOnlyPropertyAccessor() override = default;

  void Clear(Error* error) override { Set(default_value_, error); }
  T Get(Error* error) override {
    error->Populate(Error::kPermissionDenied, "Property is write-only");
    return T();
  }
  bool Set(const T& value, Error* /*error*/) override {
    if (*property_ == value) {
      return false;
    }
    *property_ = value;
    return true;
  }

 private:
  FRIEND_TEST(PropertyAccessorTest, SignedIntCorrectness);
  FRIEND_TEST(PropertyAccessorTest, UnsignedIntCorrectness);
  FRIEND_TEST(PropertyAccessorTest, StringCorrectness);
  FRIEND_TEST(PropertyAccessorTest, ByteArrayCorrectness);

  T* const property_;
  const T default_value_;
  DISALLOW_COPY_AND_ASSIGN(WriteOnlyPropertyAccessor);
};

// CustomAccessor<> allows custom getter and setter methods to be provided.
// Thus, if the state to be returned is to be derived on-demand, or if
// setting the property requires validation, we can still fit it into the
// AccessorInterface<> framework.
//
// If the property is write-only, use CustomWriteOnlyAccessor instead.
template<class C, class T>
class CustomAccessor : public AccessorInterface<T> {
 public:
  // |target| is the object on which to call the methods |getter|, |setter|
  // and |clearer|.  |setter| is allowed to be NULL, in which case we will
  // simply reject attempts to set via the accessor. |setter| should return
  // true if the value was changed, and false otherwise.  |clearer| is allowed
  // to be NULL (which is what happens if it is not passed to the constructor),
  // in which case, |setter| is called is called with the default value.
  // It is an error to pass NULL for either |target| or |getter|.
  CustomAccessor(C* target,
                 T(C::*getter)(Error* error),
                 bool(C::*setter)(const T& value, Error* error),
                 void(C::*clearer)(Error* error))
      : target_(target),
        default_value_(),
        getter_(getter),
        setter_(setter),
        clearer_(clearer) {
    DCHECK(target);
    DCHECK(getter);  // otherwise, use CustomWriteOnlyAccessor
    if (setter_) {
      Error e;
      default_value_ = Get(&e);
    }
  }
  CustomAccessor(C* target,
                 T(C::*getter)(Error* error),
                 bool(C::*setter)(const T& value, Error* error))
      : CustomAccessor(target, getter, setter, nullptr) {}
  ~CustomAccessor() override = default;

  void Clear(Error* error) override {
    if (clearer_) {
      (target_->*clearer_)(error);
    } else {
      Set(default_value_, error);
    }
  }
  T Get(Error* error) override {
    return (target_->*getter_)(error);
  }
  bool Set(const T& value, Error* error) override {
    if (setter_) {
      return (target_->*setter_)(value, error);
    } else {
      error->Populate(Error::kInvalidArguments, "Property is read-only");
      return false;
    }
  }

 private:
  C* const target_;
  // |default_value_| is non-const because it can't be initialized in
  // the initializer list.
  T default_value_;
  T(C::*const getter_)(Error* error);
  bool(C::*const setter_)(const T& value, Error* error);  // NOLINT - "casting"
  void(C::*const clearer_)(Error* error);
  DISALLOW_COPY_AND_ASSIGN(CustomAccessor);
};

// CustomWriteOnlyAccessor<> allows a custom writer method to be provided.
// Get returns an error automatically. Clear resets the value to a
// default value.
template<class C, class T>
class CustomWriteOnlyAccessor : public AccessorInterface<T> {
 public:
  // |target| is the object on which to call |setter| and |clearer|.
  //
  // |target| and |setter| must be non-NULL. |setter| should return true
  // if the value was changed, and false otherwise.
  //
  // Either |clearer| or |default_value|, but not both, must be non-NULL.
  // Whichever is non-NULL is used to clear the property.
  CustomWriteOnlyAccessor(C* target,
                          bool(C::*setter)(const T& value, Error* error),
                          void(C::*clearer)(Error* error),
                          const T* default_value)
      : target_(target),
        setter_(setter),
        clearer_(clearer),
        default_value_() {
    DCHECK(target);
    DCHECK(setter);
    DCHECK(clearer || default_value);
    DCHECK(!clearer || !default_value);
    if (default_value) {
      default_value_ = *default_value;
    }
  }
  ~CustomWriteOnlyAccessor() override = default;

  void Clear(Error* error) override {
    if (clearer_) {
      (target_->*clearer_)(error);
    } else {
      Set(default_value_, error);
    }
  }
  T Get(Error* error) override {
    error->Populate(Error::kPermissionDenied, "Property is write-only");
    return T();
  }
  bool Set(const T& value, Error* error) override {
    return (target_->*setter_)(value, error);
  }

 private:
  C* const target_;
  bool(C::*const setter_)(const T& value, Error* error);  // NOLINT - "casting"
  void(C::*const clearer_)(Error* error);
  // |default_value_| is non-const because it can't be initialized in
  // the initializer list.
  T default_value_;
  DISALLOW_COPY_AND_ASSIGN(CustomWriteOnlyAccessor);
};

// CustomReadOnlyAccessor<> allows a custom getter method to be provided.
// Set and Clear return errors automatically.
template<class C, class T>
class CustomReadOnlyAccessor : public AccessorInterface<T> {
 public:
  // |target| is the object on which to call the |getter| method.
  // |getter| is a const method.  If a non-const method needs to be used,
  // use the CustomAccessor with a NULL setter instead.
  CustomReadOnlyAccessor(C* target, T(C::*getter)(Error* error) const)
      : target_(target), getter_(getter) {
    DCHECK(target);
    DCHECK(getter);
  }
  ~CustomReadOnlyAccessor() override = default;

  void Clear(Error* error) override {
    error->Populate(Error::kInvalidArguments, "Property is read-only");
  }
  T Get(Error* error) override {
    return (target_->*getter_)(error);
  }
  bool Set(const T& value, Error* error) override {
    error->Populate(Error::kInvalidArguments, "Property is read-only");
    return false;
  }

 private:
  C* const target_;
  T(C::*const getter_)(Error* error) const;
  DISALLOW_COPY_AND_ASSIGN(CustomReadOnlyAccessor);
};

// CustomMappedAccessor<> passes an argument to the getter and setter
// so that a generic method can be used, for example one that accesses the
// property in a map.
template<class C, class T, class A>
class CustomMappedAccessor : 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. |setter| should return true if the
  // value was changed, and false otherwise.
  // |argument| is passed to the getter and setter methods to disambiguate
  // between different properties in |target|.
  // It is an error to pass NULL for any of |target|, |clearer| or |getter|.
  CustomMappedAccessor(C* target,
                       void(C::*clearer)(const A& argument, Error* error),
                       T(C::*getter)(const A& argument, Error* error),
                       bool(C::*setter)(const A& argument, const T& value,
                                        Error* error),
                       const A& argument)
      : target_(target),
        clearer_(clearer),
        getter_(getter),
        setter_(setter),
        argument_(argument) {
    DCHECK(clearer);
    DCHECK(target);
    DCHECK(getter);
  }
  ~CustomMappedAccessor() override = default;

  void Clear(Error* error) override {
    (target_->*clearer_)(argument_, error);
  }
  T Get(Error* error) override {
    return (target_->*getter_)(argument_, error);
  }
  bool Set(const T& value, Error* error) override {
    if (setter_) {
      return (target_->*setter_)(argument_, value, error);
    } else {
      error->Populate(Error::kInvalidArguments, "Property is read-only");
      return false;
    }
  }

 private:
  C* const target_;
  void(C::*const clearer_)(const A& argument, Error* error);
  T(C::*const getter_)(const A& argument, Error* error);
  bool(C::*const setter_)(const A& argument,  // NOLINT - "casting"
                          const T& value, Error* error);
  A argument_;
  DISALLOW_COPY_AND_ASSIGN(CustomMappedAccessor);
};

}  // namespace shill

#endif  // SHILL_PROPERTY_ACCESSOR_H_
