//
// 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.
//

#ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
#define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_

#include <memory>
#include <set>
#include <string>

#include <base/callback.h>
#include <base/memory/ref_counted.h>
#include <base/time/time.h>

#include "update_engine/common/clock_interface.h"
#include "update_engine/update_manager/default_policy.h"
#include "update_engine/update_manager/evaluation_context.h"
#include "update_engine/update_manager/policy.h"
#include "update_engine/update_manager/state.h"

namespace chromeos_update_manager {

// Comparator for scoped_refptr objects.
template<typename T>
struct ScopedRefPtrLess {
  bool operator()(const scoped_refptr<T>& first,
                  const scoped_refptr<T>& second) const {
    return first.get() < second.get();
  }
};

// The main Update Manager singleton class.
class UpdateManager {
 public:
  // Creates the UpdateManager instance, assuming ownership on the provided
  // |state|.
  UpdateManager(chromeos_update_engine::ClockInterface* clock,
                base::TimeDelta evaluation_timeout,
                base::TimeDelta expiration_timeout, State* state);

  virtual ~UpdateManager();

  // PolicyRequest() evaluates the given policy with the provided arguments and
  // returns the result. The |policy_method| is the pointer-to-method of the
  // Policy class for the policy request to call. The UpdateManager will call
  // this method on the right policy. The pointer |result| must not be null
  // and the remaining |args| depend on the arguments required by the passed
  // |policy_method|.
  //
  // When the policy request succeeds, the |result| is set and the method
  // returns EvalStatus::kSucceeded, otherwise, the |result| may not be set.  A
  // policy called with this method should not block (i.e. return
  // EvalStatus::kAskMeAgainLater), which is considered a programming error. On
  // failure, EvalStatus::kFailed is returned.
  //
  // An example call to this method is:
  //   um.PolicyRequest(&Policy::SomePolicyMethod, &bool_result, arg1, arg2);
  template<typename R, typename... ActualArgs, typename... ExpectedArgs>
  EvalStatus PolicyRequest(
      EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
                                          std::string*, R*,
                                          ExpectedArgs...) const,
      R* result, ActualArgs...);

  // Evaluates the given |policy_method| policy with the provided |args|
  // arguments and calls the |callback| callback with the result when done.
  //
  // If the policy implementation should block, returning a
  // EvalStatus::kAskMeAgainLater status the Update Manager will re-evaluate the
  // policy until another status is returned. If the policy implementation based
  // its return value solely on const variables, the callback will be called
  // with the EvalStatus::kAskMeAgainLater status (which indicates an error).
  template<typename R, typename... ActualArgs, typename... ExpectedArgs>
  void AsyncPolicyRequest(
      base::Callback<void(EvalStatus, const R& result)> callback,
      EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
                                          std::string*, R*,
                                          ExpectedArgs...) const,
      ActualArgs... args);

 protected:
  // The UpdateManager receives ownership of the passed Policy instance.
  void set_policy(const Policy* policy) {
    policy_.reset(policy);
  }

  // State getter used for testing.
  State* state() { return state_.get(); }

 private:
  FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsPolicy);
  FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsDefaultOnError);
  FRIEND_TEST(UmUpdateManagerTest, PolicyRequestDoesntBlockDeathTest);
  FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestDelaysEvaluation);
  FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimeoutDoesNotFire);
  FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimesOut);

  // EvaluatePolicy() evaluates the passed |policy_method| method on the current
  // policy with the given |args| arguments. If the method fails, the default
  // policy is used instead.
  template<typename R, typename... Args>
  EvalStatus EvaluatePolicy(
      EvaluationContext* ec,
      EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
                                          std::string*, R*,
                                          Args...) const,
      R* result, Args... args);

  // OnPolicyReadyToEvaluate() is called by the main loop when the evaluation
  // of the given |policy_method| should be executed. If the evaluation finishes
  // the |callback| callback is called passing the |result| and the |status|
  // returned by the policy. If the evaluation returns an
  // EvalStatus::kAskMeAgainLater state, the |callback| will NOT be called and
  // the evaluation will be re-scheduled to be called later.
  template<typename R, typename... Args>
  void OnPolicyReadyToEvaluate(
      scoped_refptr<EvaluationContext> ec,
      base::Callback<void(EvalStatus status, const R& result)> callback,
      EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
                                          std::string*, R*,
                                          Args...) const,
      Args... args);

  // Unregisters (removes from repo) a previously created EvaluationContext.
  void UnregisterEvalContext(EvaluationContext* ec);

  // The policy used by the UpdateManager. Note that since it is a const Policy,
  // policy implementations are not allowed to persist state on this class.
  std::unique_ptr<const Policy> policy_;

  // A safe default value to the current policy. This policy is used whenever
  // a policy implementation fails with EvalStatus::kFailed.
  const DefaultPolicy default_policy_;

  // State Providers.
  std::unique_ptr<State> state_;

  // Pointer to the mockable clock interface;
  chromeos_update_engine::ClockInterface* clock_;

  // Timeout for a policy evaluation.
  const base::TimeDelta evaluation_timeout_;

  // Timeout for expiration of the evaluation context, used for async requests.
  const base::TimeDelta expiration_timeout_;

  // Repository of previously created EvaluationContext objects. These are being
  // unregistered (and the reference released) when the context is being
  // destructed; alternatively, when the UpdateManager instance is destroyed, it
  // will remove all pending events associated with all outstanding contexts
  // (which should, in turn, trigger their destruction).
  std::set<scoped_refptr<EvaluationContext>,
           ScopedRefPtrLess<EvaluationContext>> ec_repo_;

  base::WeakPtrFactory<UpdateManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(UpdateManager);
};

}  // namespace chromeos_update_manager

// Include the implementation of the template methods.
#include "update_engine/update_manager/update_manager-inl.h"

#endif  // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
