//===----------------------------------------------------------------------===//
//
// 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: c++03, c++11, c++14, c++17
// XFAIL: availability-synchronization_library-missing

// ~stop_callback();

#include <atomic>
#include <cassert>
#include <chrono>
#include <functional>
#include <memory>
#include <optional>
#include <stop_token>
#include <type_traits>
#include <utility>
#include <vector>

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

struct CallbackHolder;

struct DeleteHolder {
  CallbackHolder& holder_;
  void operator()() const;
};

struct CallbackHolder {
  std::unique_ptr<std::stop_callback<DeleteHolder>> callback_;
};

void DeleteHolder::operator()() const { holder_.callback_.reset(); }

int main(int, char**) {
  // Unregisters the callback from the owned stop state, if any
  {
    std::stop_source ss;
    bool called = false;

    {
      std::stop_callback sc(ss.get_token(), [&] { called = true; });
    }
    ss.request_stop();
    assert(!called);
  }

  // The destructor does not block waiting for the execution of another
  // callback registered by an associated stop_callback.
  {
    std::stop_source ss;

    std::atomic<int> startedIndex    = 0;
    std::atomic<bool> callbackFinish = false;

    std::optional<std::stop_callback<std::function<void()>>> sc1(std::in_place, ss.get_token(), [&] {
      startedIndex = 1;
      startedIndex.notify_all();
      callbackFinish.wait(false);
    });

    std::optional<std::stop_callback<std::function<void()>>> sc2(std::in_place, ss.get_token(), [&] {
      startedIndex = 2;
      startedIndex.notify_all();
      callbackFinish.wait(false);
    });

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

    startedIndex.wait(0);

    // now one of the callback has started but not finished.
    if (startedIndex == 1) {
      sc2.reset();   // destructor should not block
    } else if (startedIndex == 2) {
      sc1.reset();   // destructor should not block
    } else {
      assert(false); // something is wrong
    }

    callbackFinish = true;
    callbackFinish.notify_all();
    thread.join();
  }

  // If callback is concurrently executing on another thread, then the
  // return from the invocation of callback strongly happens before ([intro.races])
  // callback is destroyed.
  {
    struct Callback {
      std::atomic<bool>& started_;
      std::atomic<bool>& waitDone_;
      std::atomic<bool>& finished_;
      bool moved = false;

      Callback(std::atomic<bool>& started, std::atomic<bool>& waitDone, std::atomic<bool>& finished)
          : started_(started), waitDone_(waitDone), finished_(finished) {}
      Callback(Callback&& other) : started_(other.started_), waitDone_(other.waitDone_), finished_(other.finished_) {
        other.moved = true;
      }

      void operator()() const {
        struct ScopedGuard {
          std::atomic<bool>& g_finished_;
          ~ScopedGuard() { g_finished_.store(true, std::memory_order_relaxed); }
        };

        started_ = true;
        started_.notify_all();
        waitDone_.wait(false);
        ScopedGuard g{finished_};
      }

      ~Callback() {
        if (!moved) {
          // destructor has to be called after operator() returns
          assert(finished_.load(std::memory_order_relaxed));
        }
      }
    };

    std::stop_source ss;

    std::atomic<bool> started  = false;
    std::atomic<bool> waitDone = false;
    std::atomic<bool> finished = false;

    std::optional<std::stop_callback<Callback>> sc{
        std::in_place, ss.get_token(), Callback{started, waitDone, finished}};

    auto thread1 = support::make_test_thread([&] { ss.request_stop(); });
    started.wait(false);

    auto thread2 = support::make_test_thread([&] {
      using namespace std::chrono_literals;
      std::this_thread::sleep_for(1ms);
      waitDone = true;
      waitDone.notify_all();
    });

    sc.reset(); // destructor should block until operator() returns, i.e. waitDone to be true

    thread1.join();
    thread2.join();
  }

  // If callback is executing on the current thread, then the destructor does not block ([defns.block])
  // waiting for the return from the invocation of callback.
  {
    std::stop_source ss;

    CallbackHolder holder;
    holder.callback_ = std::make_unique<std::stop_callback<DeleteHolder>>(ss.get_token(), DeleteHolder{holder});

    assert(holder.callback_ != nullptr);

    ss.request_stop(); // the callbacks deletes itself. if the destructor blocks, it would be deadlock
    assert(holder.callback_ == nullptr);
  }

  return 0;
}
