//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads
// UNSUPPORTED: libcpp-has-no-experimental-stop_token
// UNSUPPORTED: c++03, c++11, c++14, c++17
// XFAIL: availability-synchronization_library-missing

// template<class C>
// explicit stop_callback(const stop_token& st, C&& cb)
//   noexcept(is_nothrow_constructible_v<Callback, C>);

#include <atomic>
#include <cassert>
#include <chrono>
#include <stop_token>
#include <type_traits>
#include <utility>
#include <vector>

#include "make_test_thread.h"
#include "test_macros.h"

struct Cb {
  void operator()() const;
};

// Constraints: Callback and C satisfy constructible_from<Callback, C>.
static_assert(std::is_constructible_v<std::stop_callback<void (*)()>, const std::stop_token&, void (*)()>);
static_assert(!std::is_constructible_v<std::stop_callback<void (*)()>, const std::stop_token&, void (*)(int)>);
static_assert(std::is_constructible_v<std::stop_callback<Cb>, const std::stop_token&, Cb&>);
static_assert(std::is_constructible_v<std::stop_callback<Cb&>, const std::stop_token&, Cb&>);
static_assert(!std::is_constructible_v<std::stop_callback<Cb>, const std::stop_token&, int>);

// explicit
template <class T>
void conversion_test(T);

template <class T, class... Args>
concept ImplicitlyConstructible = requires(Args&&... args) { conversion_test<T>({std::forward<Args>(args)...}); };
static_assert(ImplicitlyConstructible<int, int>);
static_assert(!ImplicitlyConstructible<std::stop_callback<Cb>, const std::stop_token&, Cb>);

// noexcept
template <bool NoExceptCtor>
struct CbNoExcept {
  CbNoExcept(int) noexcept(NoExceptCtor);
  void operator()() const;
};
static_assert(std::is_nothrow_constructible_v<std::stop_callback<CbNoExcept<true>>, const std::stop_token&, int>);
static_assert(!std::is_nothrow_constructible_v<std::stop_callback<CbNoExcept<false>>, const std::stop_token&, int>);

int main(int, char**) {
  // was requested
  {
    std::stop_source ss;
    const std::stop_token st = ss.get_token();
    ss.request_stop();

    bool called = false;
    std::stop_callback sc(st, [&] { called = true; });
    assert(called);
  }

  // was not requested
  {
    std::stop_source ss;
    const std::stop_token st = ss.get_token();

    bool called = false;
    std::stop_callback sc(st, [&] { called = true; });
    assert(!called);

    ss.request_stop();
    assert(called);
  }

  // token has no state
  {
    std::stop_token st;
    bool called = false;
    std::stop_callback sc(st, [&] { called = true; });
    assert(!called);
  }

  // should not be called multiple times
  {
    std::stop_source ss;
    const std::stop_token st = ss.get_token();

    int calledTimes = 0;
    std::stop_callback sc(st, [&] { ++calledTimes; });

    std::vector<std::thread> threads;
    for (auto i = 0; i < 10; ++i) {
      threads.emplace_back(support::make_test_thread([&] { ss.request_stop(); }));
    }

    for (auto& thread : threads) {
      thread.join();
    }
    assert(calledTimes == 1);
  }

  // adding more callbacks during invoking other callbacks
  {
    std::stop_source ss;
    const std::stop_token st = ss.get_token();

    std::atomic<bool> startedFlag = false;
    std::atomic<bool> finishFlag  = false;
    std::stop_callback sc(st, [&] {
      startedFlag = true;
      startedFlag.notify_all();
      finishFlag.wait(false);
    });

    auto thread = support::make_test_thread([&] { ss.request_stop(); });

    startedFlag.wait(false);

    // first callback is still running, adding another one;
    bool secondCallbackCalled = false;
    std::stop_callback sc2(st, [&] { secondCallbackCalled = true; });

    finishFlag = true;
    finishFlag.notify_all();

    thread.join();
    assert(secondCallbackCalled);
  }

  // adding callbacks on different threads
  {
    std::stop_source ss;
    const std::stop_token st = ss.get_token();

    std::vector<std::thread> threads;
    std::atomic<int> callbackCalledTimes = 0;
    std::atomic<bool> done               = false;
    for (auto i = 0; i < 10; ++i) {
      threads.emplace_back(support::make_test_thread([&] {
        std::stop_callback sc{st, [&] { callbackCalledTimes.fetch_add(1, std::memory_order_relaxed); }};
        done.wait(false);
      }));
    }
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(1ms);
    ss.request_stop();
    done = true;
    done.notify_all();
    for (auto& thread : threads) {
      thread.join();
    }
    assert(callbackCalledTimes.load(std::memory_order_relaxed) == 10);
  }

  // correct overload
  {
    struct CBWithTracking {
      bool& lvalueCalled;
      bool& lvalueConstCalled;
      bool& rvalueCalled;
      bool& rvalueConstCalled;

      void operator()() & { lvalueCalled = true; }
      void operator()() const& { lvalueConstCalled = true; }
      void operator()() && { rvalueCalled = true; }
      void operator()() const&& { rvalueConstCalled = true; }
    };

    // RValue
    {
      bool lvalueCalled      = false;
      bool lvalueConstCalled = false;
      bool rvalueCalled      = false;
      bool rvalueConstCalled = false;
      std::stop_source ss;
      const std::stop_token st = ss.get_token();
      ss.request_stop();

      std::stop_callback<CBWithTracking> sc(
          st, CBWithTracking{lvalueCalled, lvalueConstCalled, rvalueCalled, rvalueConstCalled});
      assert(rvalueCalled);
    }

    // RValue
    {
      bool lvalueCalled      = false;
      bool lvalueConstCalled = false;
      bool rvalueCalled      = false;
      bool rvalueConstCalled = false;
      std::stop_source ss;
      const std::stop_token st = ss.get_token();
      ss.request_stop();

      std::stop_callback<const CBWithTracking> sc(
          st, CBWithTracking{lvalueCalled, lvalueConstCalled, rvalueCalled, rvalueConstCalled});
      assert(rvalueConstCalled);
    }

    // LValue
    {
      bool lvalueCalled      = false;
      bool lvalueConstCalled = false;
      bool rvalueCalled      = false;
      bool rvalueConstCalled = false;
      std::stop_source ss;
      const std::stop_token st = ss.get_token();
      ss.request_stop();
      CBWithTracking cb{lvalueCalled, lvalueConstCalled, rvalueCalled, rvalueConstCalled};
      std::stop_callback<CBWithTracking&> sc(st, cb);
      assert(lvalueCalled);
    }

    // const LValue
    {
      bool lvalueCalled      = false;
      bool lvalueConstCalled = false;
      bool rvalueCalled      = false;
      bool rvalueConstCalled = false;
      std::stop_source ss;
      const std::stop_token st = ss.get_token();
      ss.request_stop();
      CBWithTracking cb{lvalueCalled, lvalueConstCalled, rvalueCalled, rvalueConstCalled};
      std::stop_callback<const CBWithTracking&> sc(st, cb);
      assert(lvalueConstCalled);
    }
  }

  return 0;
}
