/*
 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_BASE_ASYNCINVOKER_INL_H_
#define WEBRTC_BASE_ASYNCINVOKER_INL_H_

#include "webrtc/base/bind.h"
#include "webrtc/base/callback.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/thread.h"

namespace rtc {

class AsyncInvoker;

// Helper class for AsyncInvoker. Runs a task and triggers a callback
// on the calling thread if necessary. Instances are ref-counted so their
// lifetime can be independent of AsyncInvoker.
class AsyncClosure : public RefCountInterface {
 public:
  virtual ~AsyncClosure() {}
  // Runs the asynchronous task, and triggers a callback to the calling
  // thread if needed. Should be called from the target thread.
  virtual void Execute() = 0;
};

// Simple closure that doesn't trigger a callback for the calling thread.
template <class FunctorT>
class FireAndForgetAsyncClosure : public AsyncClosure {
 public:
  explicit FireAndForgetAsyncClosure(const FunctorT& functor)
      : functor_(functor) {}
  virtual void Execute() {
    functor_();
  }
 private:
  FunctorT functor_;
};

// Base class for closures that may trigger a callback for the calling thread.
// Listens for the "destroyed" signals from the calling thread and the invoker,
// and cancels the callback to the calling thread if either is destroyed.
class NotifyingAsyncClosureBase : public AsyncClosure,
                                  public sigslot::has_slots<> {
 public:
  virtual ~NotifyingAsyncClosureBase() { disconnect_all(); }

 protected:
  NotifyingAsyncClosureBase(AsyncInvoker* invoker, Thread* calling_thread);
  void TriggerCallback();
  void SetCallback(const Callback0<void>& callback) {
    CritScope cs(&crit_);
    callback_ = callback;
  }
  bool CallbackCanceled() const { return calling_thread_ == NULL; }

 private:
  Callback0<void> callback_;
  CriticalSection crit_;
  AsyncInvoker* invoker_;
  Thread* calling_thread_;

  void CancelCallback();
};

// Closures that have a non-void return value and require a callback.
template <class ReturnT, class FunctorT, class HostT>
class NotifyingAsyncClosure : public NotifyingAsyncClosureBase {
 public:
  NotifyingAsyncClosure(AsyncInvoker* invoker,
                        Thread* calling_thread,
                        const FunctorT& functor,
                        void (HostT::*callback)(ReturnT),
                        HostT* callback_host)
      :  NotifyingAsyncClosureBase(invoker, calling_thread),
         functor_(functor),
         callback_(callback),
         callback_host_(callback_host) {}
  virtual void Execute() {
    ReturnT result = functor_();
    if (!CallbackCanceled()) {
      SetCallback(Callback0<void>(Bind(callback_, callback_host_, result)));
      TriggerCallback();
    }
  }

 private:
  FunctorT functor_;
  void (HostT::*callback_)(ReturnT);
  HostT* callback_host_;
};

// Closures that have a void return value and require a callback.
template <class FunctorT, class HostT>
class NotifyingAsyncClosure<void, FunctorT, HostT>
    : public NotifyingAsyncClosureBase {
 public:
  NotifyingAsyncClosure(AsyncInvoker* invoker,
                        Thread* calling_thread,
                        const FunctorT& functor,
                        void (HostT::*callback)(),
                        HostT* callback_host)
      : NotifyingAsyncClosureBase(invoker, calling_thread),
        functor_(functor) {
    SetCallback(Callback0<void>(Bind(callback, callback_host)));
  }
  virtual void Execute() {
    functor_();
    TriggerCallback();
  }

 private:
  FunctorT functor_;
};

}  // namespace rtc

#endif  // WEBRTC_BASE_ASYNCINVOKER_INL_H_
