//
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// Generic and provider-independent Variable subclasses. These variables can be
// used by any state provider to implement simple variables to avoid repeat the
// same common code on different state providers.

#ifndef UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
#define UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_

#include <string>

#include <base/callback.h>

#include "update_engine/update_manager/variable.h"

namespace chromeos_update_manager {

// Variable class returning a copy of a given object using the copy constructor.
// This template class can be used to define variables that expose as a variable
// any fixed object, such as the a provider's private member. The variable will
// create copies of the provided object using the copy constructor of that
// class.
//
// For example, a state provider exposing a private member as a variable can
// implement this as follows:
//
//   class SomethingProvider {
//    public:
//      SomethingProvider(...) {
//        var_something_foo = new PollCopyVariable<MyType>(foo_);
//      }
//      ...
//    private:
//     MyType foo_;
//   };
template<typename T>
class PollCopyVariable : public Variable<T> {
 public:
  // Creates the variable returning copies of the passed |ref|. The reference to
  // this object is kept and it should be available whenever the GetValue()
  // method is called. If |is_set_p| is not null, then this flag will be
  // consulted prior to returning the value, and an |errmsg| will be returned if
  // it is not set.
  PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p,
                   const std::string& errmsg)
      : Variable<T>(name, kVariableModePoll), ref_(ref), is_set_p_(is_set_p),
        errmsg_(errmsg) {}
  PollCopyVariable(const std::string& name, const T& ref, const bool* is_set_p)
      : PollCopyVariable(name, ref, is_set_p, std::string()) {}
  PollCopyVariable(const std::string& name, const T& ref)
      : PollCopyVariable(name, ref, nullptr) {}

  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
                   const T& ref, const bool* is_set_p,
                   const std::string& errmsg)
      : Variable<T>(name, poll_interval), ref_(ref), is_set_p_(is_set_p),
        errmsg_(errmsg) {}
  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
                   const T& ref, const bool* is_set_p)
      : PollCopyVariable(name, poll_interval, ref, is_set_p, std::string()) {}
  PollCopyVariable(const std::string& name, const base::TimeDelta poll_interval,
                   const T& ref)
      : PollCopyVariable(name, poll_interval, ref, nullptr) {}

 protected:
  FRIEND_TEST(UmPollCopyVariableTest, SimpleTest);
  FRIEND_TEST(UmPollCopyVariableTest, UseCopyConstructorTest);

  // Variable override.
  inline const T* GetValue(base::TimeDelta /* timeout */,
                           std::string* errmsg) override {
    if (is_set_p_ && !(*is_set_p_)) {
      if (errmsg) {
        if (errmsg_.empty())
          *errmsg = "No value set for " + this->GetName();
        else
          *errmsg = errmsg_;
      }
      return nullptr;
    }
    return new T(ref_);
  }

 private:
  // Reference to the object to be copied by GetValue().
  const T& ref_;

  // A pointer to a flag indicating whether the value is set. If null, then the
  // value is assumed to be set.
  const bool* const is_set_p_;

  // An error message to be returned when attempting to get an unset value.
  const std::string errmsg_;
};

// Variable class returning a constant value that is cached on the variable when
// it is created.
template<typename T>
class ConstCopyVariable : public Variable<T> {
 public:
  // Creates the variable returning copies of the passed |obj|. The value passed
  // is copied in this variable, and new copies of it will be returned by
  // GetValue().
  ConstCopyVariable(const std::string& name, const T& obj)
      : Variable<T>(name, kVariableModeConst), obj_(obj) {}

 protected:
  // Variable override.
  const T* GetValue(base::TimeDelta /* timeout */,
                    std::string* /* errmsg */) override {
    return new T(obj_);
  }

 private:
  // Value to be copied by GetValue().
  const T obj_;
};

// Variable class returning a copy of a value returned by a given function. The
// function is called every time the variable is being polled.
template<typename T>
class CallCopyVariable : public Variable<T> {
 public:
  CallCopyVariable(const std::string& name, base::Callback<T(void)> func)
      : Variable<T>(name, kVariableModePoll), func_(func) {}
  CallCopyVariable(const std::string& name,
                   const base::TimeDelta poll_interval,
                   base::Callback<T(void)> func)
      : Variable<T>(name, poll_interval), func_(func) {}

 protected:
  // Variable override.
  const T* GetValue(base::TimeDelta /* timeout */,
                    std::string* /* errmsg */) override {
    if (func_.is_null())
      return nullptr;
    return new T(func_.Run());
  }

 private:
  FRIEND_TEST(UmCallCopyVariableTest, SimpleTest);

  // The function to be called, stored as a base::Callback.
  base::Callback<T(void)> func_;

  DISALLOW_COPY_AND_ASSIGN(CallCopyVariable);
};


// A Variable class to implement simple Async variables. It provides two methods
// SetValue and UnsetValue to modify the current value of the variable and
// notify the registered observers whenever the value changed.
//
// The type T needs to be copy-constructible, default-constructible and have an
// operator== (to determine if the value changed), which makes this class
// suitable for basic types.
template<typename T>
class AsyncCopyVariable : public Variable<T> {
 public:
  explicit AsyncCopyVariable(const std::string& name)
      : Variable<T>(name, kVariableModeAsync), has_value_(false) {}

  AsyncCopyVariable(const std::string& name, const T value)
      : Variable<T>(name, kVariableModeAsync),
        has_value_(true), value_(value) {}

  void SetValue(const T& new_value) {
    bool should_notify = !(has_value_ && new_value == value_);
    value_ = new_value;
    has_value_ = true;
    if (should_notify)
      this->NotifyValueChanged();
  }

  void UnsetValue() {
    if (has_value_) {
      has_value_ = false;
      this->NotifyValueChanged();
    }
  }

 protected:
  // Variable override.
  const T* GetValue(base::TimeDelta /* timeout */,
                    std::string* errmsg) override {
    if (!has_value_) {
      if (errmsg)
        *errmsg = "No value set for " + this->GetName();
      return nullptr;
    }
    return new T(value_);
  }

 private:
  // Whether the variable has a value set.
  bool has_value_;

  // Copy of the object to be returned by GetValue().
  T value_;
};

}  // namespace chromeos_update_manager

#endif  // UPDATE_ENGINE_UPDATE_MANAGER_GENERIC_VARIABLES_H_
