// Copyright 2018 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_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_TASK_DOMAIN_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_TASK_DOMAIN_H_

#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/dispatcher.h>
#include <lib/fit/function.h>
#include <zircon/assert.h>

#include <string>

namespace bt {

// A task domain is a mixin for objects that maintain state that needs to be
// accessed exclusively on a specific dispatcher.
//
//   * A TaskDomain can be initialized with a task runner representing the
//     serialization domain. If not, TaskDomain will spawn a thread with the
//     runner.
//
//   * TaskDomain provides a PostMessage() method which can be used to schedule
//     a task on the domain. The TaskDomain is guaranteed to remain alive during
//     the task execution. This guarantee requires that T derive from
//     fbl::RefCounted<T>.
//
//   * Tasks that are posted or run after clean up will be ignored. The
//     ScheduleCleanUp() method must be called before all references to T are
//     dropped.
//
//     T must provide a CleanUp() method, which will be scheduled on the
//     domain's task runner by ScheduleCleanUp(). This can be used to clean up
//     state that is restricted to the task runner.
//
// EXAMPLE:
//
//   class MyObject : public fbl::RefCounted<MyObject>,
//                    public TaskDomain<MyObject> {
//    public:
//     // Initialize by spawning a thread with a dispatcher owned by this
//     // domain.
//     MyObject() : TaskDomain<MyObject>(this, "my-thread") {}
//
//     // Initialize to run on |dispatcher|.
//     explicit MyObject(async_dispatcher_t* dispatcher)
//        : TaskDomain<MyObject>(this, dispatcher) {}
//
//     void CleanUp()
//
//    private:
//     int foo_;
//   };
//
// If MyObject indirectly inherits from fbl::RefCounted, the base type needs to
// be supplied using an additional template parameter:
//
//   class MyBase : public fbl::RefCounted<MyBase> {};
//
//   class MyObject : public MyBase, public TaskDomain<MyObject, MyBase> {
//    public:
//     ...
//   };
//
// If CleanUp() should be private:
//
//   class MyObject : public fbl::RefCounted<MyObject>,
//                    public TaskDomain<MyObject> {
//    public:
//     ...
//    private:
//     BT_FRIEND_TASK_DOMAIN(MyObject);
//
//     void CleanUp() { ... }
//   };
//

namespace internal {
DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_clean_up, CleanUp, void (T::*)(void));
}  // namespace internal

template <typename T, typename RefCountedType = T>
class TaskDomain {
 protected:
  // Initializes this domain by spawning a new thread with a dispatcher.
  // |name| is assigned to the thread.
  TaskDomain(T* obj, std::string name) {
    Init(obj);

    loop_ = std::make_unique<async::Loop>(&kAsyncLoopConfigNoAttachToThread);
    loop_->StartThread(name.c_str());
    dispatcher_ = loop_->dispatcher();
  }

  // Initializes this domain by assigning the given |dispatcher| to it.
  TaskDomain(T* obj, async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {
    Init(obj);

    ZX_DEBUG_ASSERT(dispatcher_);
  }

  virtual ~TaskDomain() {
    ZX_DEBUG_ASSERT_MSG(!alive_,
                        "ScheduleCleanUp() must be called before destruction");
  }

  // Runs the object's CleanUp() handler on the domain's dispatcher. Quits the
  // event loop if the domain owns its thread.
  void ScheduleCleanUp() {
    PostMessage([obj = obj_, this] {
      alive_ = false;
      obj->CleanUp();

      // Quit the thread if it's owned by this object.
      if (loop_) {
        loop_->Quit();
      }
    });

    // Block until the clean up task has run.
    if (loop_) {
      loop_->JoinThreads();
    }
  }

  async_dispatcher_t* dispatcher() const { return dispatcher_; }

  void PostMessage(fit::closure func) {
    // |objref| is captured here to make sure |obj_| stays alive until |func|
    // has run.
    async::PostTask(dispatcher_, [this, func = std::move(func),
                                  objref = fbl::WrapRefPtr(obj_)] {
      if (alive_) {
        func();
      }
    });
  }

  // Asserts that this domain's dispatcher is assigned as the current thread's
  // default. This is purely intended for debug assertions and should not be
  // used for any other purpose.
  inline void AssertOnDispatcherThread() const {
    ZX_DEBUG_ASSERT(async_get_default_dispatcher() == dispatcher());
  }

  // Returns true if this domain is still alive. This function is only safe to
  // call on the domain thread.
  bool alive() const {
    AssertOnDispatcherThread();
    return alive_;
  }

 private:
  void Init(T* obj) {
    ZX_DEBUG_ASSERT(obj);
    obj_ = obj;
    alive_ = true;

    static_assert(std::is_base_of<fbl::RefCounted<RefCountedType>, T>::value,
                  "T must support fbl::RefPtr");
    static_assert(std::is_base_of<TaskDomain<T, RefCountedType>, T>::value,
                  "TaskDomain can only be used as a mixin");
    static_assert(internal::has_clean_up<T>::value,
                  "T must provide a CleanUp() method");
  }

  T* obj_;
  std::atomic_bool alive_;

  // |loop_| is null if this TaskDomain gets initialized with an existing
  // dispatcher. Otherwise it will be valid and |dispatcher_| will point to
  // |loop_|'s dispatcher. |dispatcher_| is never null.
  async_dispatcher_t* dispatcher_;
  std::unique_ptr<async::Loop> loop_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TaskDomain);
};

#define BT_FRIEND_TASK_DOMAIN(Type) BT_FRIEND_TASK_DOMAIN_FULL(Type, Type)
#define BT_FRIEND_TASK_DOMAIN_FULL(Type, RefCountedType) \
  friend class bt::TaskDomain<Type, RefCountedType>;     \
  friend struct bt::internal::has_clean_up<Type>

}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_TASK_DOMAIN_H_
