// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "bluetooth/dispatcher/catch_all_forwarder.h"

#include <memory>

#include <base/memory/ref_counted.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>

#include "bluetooth/dispatcher/test_helper.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SaveArgPointee;

namespace bluetooth {

namespace {

constexpr char kRootPath[] = "/";
constexpr char kServiceDestination[] = ":1.100";

constexpr char kTestInterface[] = "org.test.TestInterface";
constexpr char kTestMethod[] = "TestMethod";
constexpr char kTestPath[] = "/org/test/object";
constexpr char kTestSender[] = ":1.1";

constexpr char kTestMethodCallString[] = "The Method Call";
constexpr char kTestResponseString[] = "The Response";

constexpr char kTestErrorName[] = "org.example.Error";
constexpr char kTestErrorResponseString[] = "Example Error";

constexpr int kTestSerial = 10;

}  // namespace

class CatchAllForwarderTest : public ::testing::Test {
 public:
  void SetUp() override {
    from_bus_ = new dbus::MockBus(dbus::Bus::Options());
    to_bus_ = new dbus::MockBus(dbus::Bus::Options());
    EXPECT_CALL(*from_bus_, AssertOnDBusThread()).Times(AnyNumber());
    catch_all_forwarder_ = std::make_unique<CatchAllForwarder>(
        from_bus_, to_bus_, kServiceDestination);
  }

  void StubHandleTestMethod(dbus::MethodCall* method_call,
                            int timeout_ms,
                            dbus::ObjectProxy::ResponseCallback* callback,
                            dbus::ObjectProxy::ErrorCallback* error_callback) {
    StubHandleMethod(kTestInterface, kTestMethod, kTestMethodCallString,
                     kTestResponseString, "" /* error_name */,
                     "" /* error_message */, method_call, timeout_ms, callback,
                     error_callback);
  }

  void StubHandleTestMethodError(
      dbus::MethodCall* method_call,
      int timeout_ms,
      dbus::ObjectProxy::ResponseCallback* callback,
      dbus::ObjectProxy::ErrorCallback* error_callback) {
    StubHandleMethod(kTestInterface, kTestMethod, kTestMethodCallString,
                     kTestResponseString, kTestErrorName,
                     kTestErrorResponseString, method_call, timeout_ms,
                     callback, error_callback);
  }

 protected:
  scoped_refptr<dbus::MockBus> from_bus_;
  scoped_refptr<dbus::MockBus> to_bus_;
  std::unique_ptr<CatchAllForwarder> catch_all_forwarder_;
};

TEST_F(CatchAllForwarderTest, ForwardMethod) {
  DBusObjectPathVTable vtable;
  EXPECT_CALL(*from_bus_, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_CALL(*from_bus_,
              TryRegisterFallback(dbus::ObjectPath(kRootPath), _, _, _))
      .WillOnce(DoAll(SaveArgPointee<1>(&vtable), Return(true)));

  catch_all_forwarder_->Init();
  ASSERT_TRUE(vtable.message_function != nullptr);

  dbus::MethodCall method_call(kTestInterface, kTestMethod);
  method_call.SetPath(dbus::ObjectPath(kTestPath));
  method_call.SetSender(kTestSender);
  method_call.SetSerial(kTestSerial);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kTestMethodCallString);

  scoped_refptr<dbus::MockObjectProxy> object_proxy = new dbus::MockObjectProxy(
      from_bus_.get(), kServiceDestination, dbus::ObjectPath(kTestPath));
  EXPECT_CALL(*to_bus_,
              GetObjectProxy(kServiceDestination, dbus::ObjectPath(kTestPath)))
      .WillOnce(Return(object_proxy.get()));
  EXPECT_CALL(*object_proxy, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &CatchAllForwarderTest::StubHandleTestMethod));

  DBusMessage* raw_response = nullptr;
  EXPECT_CALL(*from_bus_, Send(_, _))
      .WillOnce(Invoke([&raw_response](DBusMessage* msg, uint32_t* serial) {
        raw_response = dbus_message_copy(msg);
      }));
  vtable.message_function(nullptr /* connection */, method_call.raw_message(),
                          catch_all_forwarder_.get());

  ASSERT_NE(nullptr, raw_response);
  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromRawMessage(raw_response);

  std::string response_string;
  dbus::MessageReader reader(response.get());
  reader.PopString(&response_string);
  // Check that the response is the forwarded response of the stub method
  // handler.
  EXPECT_EQ(kTestSender, response->GetDestination());
  EXPECT_EQ(kTestSerial, response->GetReplySerial());
  EXPECT_EQ(kTestResponseString, response_string);

  // Test message forwarding again, but this time the method returns error.
  EXPECT_CALL(*to_bus_,
              GetObjectProxy(kServiceDestination, dbus::ObjectPath(kTestPath)))
      .WillOnce(Return(object_proxy.get()));
  EXPECT_CALL(*object_proxy, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(
          Invoke(this, &CatchAllForwarderTest::StubHandleTestMethodError));
  EXPECT_CALL(*from_bus_, Send(_, _))
      .WillOnce(Invoke([&raw_response](DBusMessage* msg, uint32_t* serial) {
        raw_response = dbus_message_copy(msg);
      }));
  vtable.message_function(nullptr /* connection */, method_call.raw_message(),
                          catch_all_forwarder_.get());
  ASSERT_NE(nullptr, raw_response);
  response = dbus::ErrorResponse::FromRawMessage(raw_response);
  dbus::MessageReader error_reader(response.get());
  error_reader.PopString(&response_string);
  // Check that the response is the forwarded response of the stub method
  // handler.
  EXPECT_EQ(kTestSender, response->GetDestination());
  EXPECT_EQ(kTestSerial, response->GetReplySerial());
  EXPECT_EQ(kTestErrorName, response->GetErrorName());
  EXPECT_EQ(kTestErrorResponseString, response_string);
}

}  // namespace bluetooth
