// Copyright 2017 The Fuchsia 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 SRC_LIB_FXL_FUNCTIONAL_CANCELABLE_CALLBACK_H_
#define SRC_LIB_FXL_FUNCTIONAL_CANCELABLE_CALLBACK_H_

#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>

#include <functional>

#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace fxl {

// CancelableCallback is a wrapper around fit::function that allows the
// cancellation of a callback. CancelableCallback takes a reference on the
// wrapped callback until this object is destroyed or Reset()/Cancel() are
// called.
//
// THREAD-SAFETY:
//
// CancelableCallback objects must be created on, posted to, canceled on, and
// destroyed on the same thread.
//
//
// EXAMPLE USAGE:
//
// void MyTimeoutCallback(std::string message) {
//   FX_LOGS(INFO) << "Timeout has expired: " << message
// }
//
// CancelableClosure cancelable(
//     std::bind(&MyTimeoutCallback, "Drinks at Foo Bar!"));
//
// my_task_runner->PostDelayedTask(cancelable.callback(),
//                                 TimeDelta::FromSeconds(5));
// ...
//
// cancelable.Cancel();  // Assuming this happens before the 5 seconds expire.
template <typename Sig>
class CancelableCallback;

template <typename... Args>
class CancelableCallback<void(Args...)> {
 public:
  CancelableCallback() : weak_ptr_factory_(this) {}

  explicit CancelableCallback(fit::function<void(Args...)> callback)
      : callback_(std::move(callback)), weak_ptr_factory_(this) {
    FX_DCHECK(callback_);
    BindWrapper();
  }

  // Cancels and drops the reference to the wrapped callback.
  void Cancel() {
    weak_ptr_factory_.InvalidateWeakPtrs();
    wrapper_ = nullptr;
    callback_ = nullptr;
  }

  // Returns true if the wrapped callback has been canceled.
  bool IsCanceled() const { return !callback_; }

  // Returns a callback that can be disabled by calling Cancel(). This returns a
  // null callback if this object currently does not wrap around a callback,
  // e.g. after a call to Cancel() or when in default-constructed state.
  fit::function<void(Args...)> callback() { return wrapper_.share(); }

  // Sets |callback| as the closure that may be canceled. |callback| may not be
  // null. Outstanding and any previously wrapped callbacks are canceled.
  void Reset(fit::function<void(Args...)> callback) {
    FX_DCHECK(callback);
    Cancel();

    callback_ = std::move(callback);
    BindWrapper();
  }

 private:
  void BindWrapper() {
    auto self = weak_ptr_factory_.GetWeakPtr();
    wrapper_ = [self](Args... args) {
      if (!self)
        return;
      FX_DCHECK(self->callback_);
      self->callback_(std::forward<Args>(args)...);
    };
  }

  // The closure that wraps around |callback_|. This acts as the cancelable
  // closure that gets vended out to clients.
  fit::function<void(Args...)> wrapper_;

  // The stored closure that may be canceled.
  fit::function<void(Args...)> callback_;

  // Used to make sure that |wrapper_| is not run when this object is destroyed.
  fxl::WeakPtrFactory<CancelableCallback> weak_ptr_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(CancelableCallback);
};

using CancelableClosure = CancelableCallback<void(void)>;

}  // namespace fxl

#endif  // SRC_LIB_FXL_FUNCTIONAL_CANCELABLE_CALLBACK_H_
