//
// Copyright (C) 2015 The Android Open Source Project
//
// 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 UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_
#define UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_

#include <memory>
#include <set>
#include <string>
#include <utility>

#include <base/bind.h>
#include <brillo/message_loops/message_loop.h>
#include <gmock/gmock.h>

namespace chromeos_update_engine {
namespace dbus_test_utils {

#define MOCK_SIGNAL_HANDLER_EXPECT_SIGNAL_HANDLER(                             \
    mock_signal_handler, mock_proxy, signal)                                   \
  do {                                                                         \
    EXPECT_CALL((mock_proxy),                                                  \
                DoRegister##signal##SignalHandler(::testing::_, ::testing::_)) \
        .WillOnce(::chromeos_update_engine::dbus_test_utils::GrabCallbacks(    \
            &(mock_signal_handler)));                                          \
  } while (false)

template <typename T>
class MockSignalHandler {
 public:
  MockSignalHandler() = default;
  ~MockSignalHandler() {
    if (callback_connected_task_ != brillo::MessageLoop::kTaskIdNull)
      brillo::MessageLoop::current()->CancelTask(callback_connected_task_);
  }

  // Returns whether the signal handler is registered.
  bool IsHandlerRegistered() const { return signal_callback_ != nullptr; }

  const base::Callback<T>& signal_callback() { return *signal_callback_.get(); }

  void GrabCallbacks(
      const base::Callback<T>& signal_callback,
      dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) {
    signal_callback_.reset(new base::Callback<T>(signal_callback));
    on_connected_callback_.reset(new dbus::ObjectProxy::OnConnectedCallback(
        std::move(*on_connected_callback)));
    // Notify from the main loop that the callback was connected.
    callback_connected_task_ = brillo::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&MockSignalHandler<T>::OnCallbackConnected,
                   base::Unretained(this)));
  }

 private:
  void OnCallbackConnected() {
    callback_connected_task_ = brillo::MessageLoop::kTaskIdNull;
    std::move(*on_connected_callback_).Run("", "", true);
  }

  brillo::MessageLoop::TaskId callback_connected_task_{
      brillo::MessageLoop::kTaskIdNull};

  std::unique_ptr<base::Callback<T>> signal_callback_;
  std::unique_ptr<dbus::ObjectProxy::OnConnectedCallback>
      on_connected_callback_;
};

// Defines the action that will call MockSignalHandler<T>::GrabCallbacks for the
// right type.
ACTION_P(GrabCallbacks, mock_signal_handler) {
  mock_signal_handler->GrabCallbacks(arg0, arg1);
}

}  // namespace dbus_test_utils
}  // namespace chromeos_update_engine

#endif  // UPDATE_ENGINE_CROS_DBUS_TEST_UTILS_H_
