// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

// Most code of this file is copied from rocksdb SyncPoint.
// https://github.com/facebook/rocksdb

#pragma once
// clang-format off
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <any>

namespace doris {

#define SYNC_POINT_HOOK_RETURN_VALUE(expr, point_name, ...)                              \
    [&]() mutable {                                                                      \
        TEST_SYNC_POINT_RETURN_WITH_VALUE(point_name, decltype((expr)) {}, __VA_ARGS__); \
        return (expr);                                                                   \
    }()

// This class provides facility to reproduce race conditions deterministically
// in unit tests.
// Developer could specify sync points in the codebase via TEST_SYNC_POINT.
// Each sync point represents a position in the execution stream of a thread.
// In the unit test, 'Happens After' relationship among sync points could be
// setup via SyncPoint::load_dependency, to reproduce a desired interleave of
// threads execution.
// Refer to (DBTest,TransactionLogIteratorRace), for an example use case.
class SyncPoint {
public:
  static SyncPoint* get_instance();
  SyncPoint(const SyncPoint&) = delete;
  SyncPoint& operator=(const SyncPoint&) = delete;
  ~SyncPoint();
  struct SyncPointPair {
    std::string predecessor;
    std::string successor;
  };

  // call once at the beginning of a test to setup the dependency between
  // sync points
  //
  // Example:
  // load_dependency({{"point1", "point2"},
  //                  {"point2", "point3"},
  //                  {"point3", "point4"}});
  //
  //    test case thread            thread for object being tested
  //        |                                  |
  //        |                                  |
  //        | \-------------0-------------\    |
  //        |                              \-> x  sync point1 set in code
  //        |    /----------1----------------/ |
  // point2 o <-/                          /-> x  sync point4 set in code
  //        |                             /    |
  //        z                            /     |
  //        z     /---------2-----------/      |  there may be nothing
  //        |    /                             |  between point1 point4
  // ponit3 o --/                              |  they are for sync
  //        |                                  |  between test case and object
  //        v                                  v
  //
  // vertical arrow means the procedure of each thread, the running order will
  // be:
  // test case thread -> point1 -> point2 -> point3 -> point4 -> object being
  // tested
  //
  // we may do a lot of things between point2 and point3, say, change the
  // object's status, call another method, propagate data race and etc.
  void load_dependency(const std::vector<SyncPointPair>& dependencies);

  // call once at the beginning of a test to setup the dependency between
  // sync points and setup markers indicating the successor is only enabled
  // when it is processed on the same thread as the predecessor.
  // When adding a marker, it implicitly adds a dependency for the marker pair.
  void load_dependency_and_markers(
                                const std::vector<SyncPointPair>& dependencies,
                                const std::vector<SyncPointPair>& markers);

  class CallbackGuard {
  public:
    CallbackGuard() = default;
    explicit CallbackGuard(std::string point) : _point(std::move(point)) {}
    ~CallbackGuard() {
      if (!_point.empty()) {
        get_instance()->clear_call_back(_point);
      }
    }
    CallbackGuard(const CallbackGuard&) = delete;
    CallbackGuard& operator=(const CallbackGuard&) = delete;

    CallbackGuard(CallbackGuard&& other) noexcept {
      if (!_point.empty() && _point != other._point) {
        get_instance()->clear_call_back(_point);
      }
      _point = std::move(other._point);
    }

    CallbackGuard& operator=(CallbackGuard&& other) noexcept {
      if (!_point.empty() && _point != other._point) {
        get_instance()->clear_call_back(_point);
      }
      _point = std::move(other._point);
      return *this;
    };

  private:
    std::string _point;
  };

  // The argument to the callback is passed through from
  // TEST_SYNC_POINT_CALLBACK(); nullptr if TEST_SYNC_POINT or
  // TEST_IDX_SYNC_POINT was used.
  // If `guard` is not nullptr, method will return a `CallbackGuard` object which will clear the
  // callback when it is destructed.
  void set_call_back(const std::string& point,
                     const std::function<void(std::vector<std::any>&&)>& callback,
                     CallbackGuard* guard = nullptr);

  // Clear callback function by point
  void clear_call_back(const std::string& point);

  // Clear all call back functions.
  void clear_all_call_backs();

  // Enable sync point processing (disabled on startup)
  void enable_processing();

  // Disable sync point processing
  void disable_processing();

  // Remove the execution trace of all sync points
  void clear_trace();

  // Triggered by TEST_SYNC_POINT, blocking execution until all predecessors
  // are executed.
  // And/or call registered callback function, with argument `cb_args`
  void process(const std::string& point, std::vector<std::any>&& cb_args = {});

  // Check if this point is registered
  bool has_point(const std::string& point);

  // Get this point if enabled
  bool get_enable();
  // TODO: it might be useful to provide a function that blocks until all
  //       sync points are cleared.
  // We want this to be public so we can subclass the implementation
  struct Data;

private:
   // Singleton
  SyncPoint();
  Data* impl_; // impletation which is hidden in cpp file
};

template <class T>
T try_any_cast(const std::any& a) {
  try {
    return std::any_cast<T>(a);
  } catch (const std::bad_any_cast& e) { 
    std::cerr << e.what() << " expected=" << typeid(T).name() << " actual=" << a.type().name() << std::endl;
    throw e;
  }
}

template <typename T>
auto try_any_cast_ret(std::vector<std::any>& any) {
    return try_any_cast<std::pair<T, bool>*>(any.back());
}

} // namespace doris

#define SYNC_POINT(x) doris::SyncPoint::get_instance()->process(x)
#define IDX_SYNC_POINT(x, index) \
    doris::SyncPoint::get_instance()->process(x + std::to_string(index))
#define SYNC_POINT_CALLBACK(x, ...) doris::SyncPoint::get_instance()->process(x, {__VA_ARGS__})
#define SYNC_POINT_RETURN_WITH_VALUE(x, default_ret_val, ...) \
{ \
  auto sync_point = doris::SyncPoint::get_instance(); \
  if (sync_point->get_enable() && sync_point->has_point(x)) { \
    std::pair ret {default_ret_val, false}; \
    std::vector<std::any> args {__VA_ARGS__}; \
    args.emplace_back(&ret); \
    sync_point->process(x, std::move(args)); \
    if (ret.second) return std::move(ret.first); \
  } \
}
#define SYNC_POINT_RETURN_WITH_VOID(x, ...) \
{ \
  bool pred = false; \
  std::vector<std::any> args {__VA_ARGS__}; \
  args.emplace_back(&pred); \
  doris::SyncPoint::get_instance()->process(x, std::move(args)); \
  if (pred) return; \
}
#define SYNC_POINT_SINGLETON() (void)doris::SyncPoint::get_instance() 

// TEST_SYNC_POINT is no op in release build.
// Turn on this feature by defining the macro
#if !defined(BE_TEST) && !defined(ENABLE_INJECTION_POINT)
# define TEST_SYNC_POINT(x)
# define TEST_IDX_SYNC_POINT(x, index)
# define TEST_SYNC_POINT_CALLBACK(x, ...)
# define TEST_SYNC_POINT_RETURN_WITH_VALUE(x, default_ret_val, ...)
# define TEST_SYNC_POINT_RETURN_WITH_VOID(x, ...)
// seldom called
# define TEST_SYNC_POINT_SINGLETON()
#else
// Use TEST_SYNC_POINT to specify sync points inside code base.
// Sync points can have happens-after depedency on other sync points,
// configured at runtime via SyncPoint::load_dependency. This could be
// utilized to re-produce race conditions between threads.
# define TEST_SYNC_POINT(x) SYNC_POINT(x)
# define TEST_IDX_SYNC_POINT(x, index) IDX_SYNC_POINT(x, index)
# define TEST_SYNC_POINT_CALLBACK(x, ...) SYNC_POINT_CALLBACK(x, __VA_ARGS__)
# define TEST_SYNC_POINT_SINGLETON() SYNC_POINT_SINGLETON()

/**
 * Inject return points for testing.
 *
 * Currently we can only insert more points to get context from tested thread
 * and process in testing thread, e.g.
 *
 * tested thread:
 * ...
 * TEST_SYNC_POINT_RETURN_WITH_VALUE("point_ret", int(0), ctx0);
 * ...
 *
 * testing thread:
 * sync_point->add("point_ret", [](auto&& args) {
 *     auto ctx0 = try_any_cast<bool>(args[0]);
 *     auto pair = try_any_cast<std::pair<int, bool>*>(args.back());
 *     pair->first = ...;
 *     pair->second = ctx0; });
 *
 * See sync_piont_test.cpp for more details.
 */
#pragma GCC diagnostic ignored "-Waddress"
# define TEST_SYNC_POINT_RETURN_WITH_VALUE(x, default_ret_val, ...) SYNC_POINT_RETURN_WITH_VALUE(x, default_ret_val, __VA_ARGS__)
# define TEST_SYNC_POINT_RETURN_WITH_VOID(x, ...) SYNC_POINT_RETURN_WITH_VOID(x, __VA_ARGS__)

#endif // BE_TEST

// TODO: define injection point in production env.
//       the `if` expr can be live configure of the application
#ifndef ENABLE_INJECTION_POINT
# define TEST_INJECTION_POINT(x)
# define TEST_IDX_INJECTION_POINT(x, index)
# define TEST_INJECTION_POINT_CALLBACK(x, ...)
# define TEST_INJECTION_POINT_RETURN_WITH_VALUE(x, default_ret_val, ...)
# define TEST_INJECTION_POINT_RETURN_WITH_VOID(x, ...)
# define TEST_INJECTION_POINT_SINGLETON()
#else
# define TEST_INJECTION_POINT(x) SYNC_POINT(x);
# define TEST_IDX_INJECTION_POINT(x, index) IDX_SYNC_POINT(x, index);
# define TEST_INJECTION_POINT_CALLBACK(x, ...) SYNC_POINT_CALLBACK(x, __VA_ARGS__);
# define TEST_INJECTION_POINT_SINGLETON() SYNC_POINT_SINGLETON();
# define TEST_INJECTION_POINT_RETURN_WITH_VALUE(x, default_ret_val, ...) SYNC_POINT_RETURN_WITH_VALUE(x, default_ret_val, __VA_ARGS__);
# define TEST_INJECTION_POINT_RETURN_WITH_VOID(x, ...) SYNC_POINT_RETURN_WITH_VOID(x, __VA_ARGS__);
#endif // ENABLE_INJECTION_POINT

// clang-format on
// vim: et tw=80 ts=2 sw=2 cc=80:
