// 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-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.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>(&kAsyncLoopConfigNoAttachToCurrentThread);
    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::RefPtr(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_
