// Copyright 2019 The Marl Authors.
//
// 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 marl_blocking_call_h
#define marl_blocking_call_h

#include "defer.h"
#include "waitgroup.h"

#include <thread>
#include <type_traits>
#include <utility>

namespace marl {
namespace detail {

template <typename RETURN_TYPE>
class OnNewThread {
 public:
  template <typename F, typename... Args>
  inline static RETURN_TYPE call(F&& f, Args&&... args) {
    RETURN_TYPE result;
    WaitGroup wg(1);
    auto thread = std::thread(
        [&](Args&&... args) {
          defer(wg.done());
          result = f(std::forward<Args>(args)...);
        },
        std::forward<Args>(args)...);
    wg.wait();
    thread.join();
    return result;
  }
};

template <>
class OnNewThread<void> {
 public:
  template <typename F, typename... Args>
  inline static void call(F&& f, Args&&... args) {
    WaitGroup wg(1);
    auto thread = std::thread(
        [&](Args&&... args) {
          defer(wg.done());
          f(std::forward<Args>(args)...);
        },
        std::forward<Args>(args)...);
    wg.wait();
    thread.join();
  }
};

}  // namespace detail

// blocking_call() calls the function F on a new thread, yielding this fiber
// to execute other tasks until F has returned.
//
// Example:
//
//  void runABlockingFunctionOnATask()
//  {
//      // Schedule a task that calls a blocking, non-yielding function.
//      yarn::schedule([=] {
//          // call_blocking_function() may block indefinitely.
//          // Ensure this call does not block other tasks from running.
//          auto result = yarn::blocking_call(call_blocking_function);
//          // call_blocking_function() has now returned.
//          // result holds the return value of the blocking function call.
//      });
//  }
template <typename F, typename... Args>
auto inline blocking_call(F&& f, Args&&... args) -> decltype(f(args...)) {
  return detail::OnNewThread<decltype(f(args...))>::call(
      std::forward<F>(f), std::forward<Args>(args)...);
}

}  // namespace marl

#endif  // marl_blocking_call_h
