/*
 *  Copyright 2025 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef RTC_BASE_SIGSLOT_TRAMPOLINE_H_
#define RTC_BASE_SIGSLOT_TRAMPOLINE_H_

#include <utility>

#include "absl/functional/any_invocable.h"
#include "rtc_base/callback_list.h"
#include "rtc_base/third_party/sigslot/sigslot.h"

namespace webrtc {
// A template to simplify the replacement of sigslot::Signal with a
// CallbackList.

// THIS IS A TEMPORARY OBJECT:
// Once all callers have converted to Subscribe* and Notify*, the signal
// and the trampoline can be replaced with a CallbackList, or, for the case
// where only one listener can ever exist, a simple callback.

// Usage, for class MyClass and signal SignalMyNamedEvent:
// class MyClass {
//   MyClass()
//     : my_named_event_trampoline_(this) {}
//   // existing:
//   sigslot::signal0<> SignalMyNamedEvent;
//   // new, this is what we want callers to use instead
//   void NotifyMyNamedEvent() { SignalMyNamedEvent(); }
//   void SubscribeMyNamedEvent(absl::AnyInvocable<void()> callback) {
//     my_named_event_trampoline_.Subscribe(std::move(callback));
//   }
//   private:
//    SignalTrampoline<MyClass, &MyClass::SignalMyNamedEvent>
//        my_named_event_trampoline_;
//  }
//
// At caller, replace:
//     my_class_object.SignalMyNamedEvent.connect(target, function)
// with:
//     my_class_object.SubscribeMyNamedEvent([target]{ target.function(); }
// Note that the SubscribeMyNamedEvent will NOT guarantee that the target
// continues to exist; if there is any doubt about that, use a SafeInvocable:
//     my_class_object.SubscibeMyNamedEvent(
//         SafeInvocable(target.safety_flag_.flag(),
//                       [target] { target.function(); }
namespace internal {
template <typename MemberPtrT>
struct member_pointer_traits;

// Used to find the type of ClassT::Member
template <typename ClassT, typename MemberT>
struct member_pointer_traits<MemberT ClassT::*> {
  using member_type = MemberT;
};

template <typename SignalT>
class SignalTrampolineBase;

template <typename... Args>
class SignalTrampolineBase<sigslot::signal<Args...>>
    : public sigslot::has_slots<> {
 public:
  void Subscribe(absl::AnyInvocable<void(Args...)> callback) {
    callbacks_.AddReceiver(std::move(callback));
  }
  void Subscribe(const void* tag, absl::AnyInvocable<void(Args...)> callback) {
    callbacks_.AddReceiver(tag, std::move(callback));
  }
  void Unsubscribe(const void* tag) { callbacks_.RemoveReceivers(tag); }
  void Notify(Args... args) { callbacks_.Send(args...); }

 private:
  CallbackList<Args...> callbacks_;
};

template <typename T, auto member_signal>
using SignalTrampolineMemberBase =
    SignalTrampolineBase<typename internal::member_pointer_traits<
        decltype(member_signal)>::member_type>;

}  // namespace internal

template <class T, auto member_signal>
class SignalTrampoline
    : public internal::SignalTrampolineMemberBase<T, member_signal> {
 private:
  using Base = internal::SignalTrampolineMemberBase<T, member_signal>;

 public:
  explicit SignalTrampoline(T* that) {
    (that->*member_signal).connect(static_cast<Base*>(this), &Base::Notify);
  }
};

}  // namespace webrtc

#endif  // RTC_BASE_SIGSLOT_TRAMPOLINE_H_
