// Copyright (c) 2012 The Chromium 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 "chromeos/dbus/blocking_method_caller.h"

#include <memory>

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/task_runner.h"
#include "dbus/message.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

namespace chromeos {

namespace {

class FakeTaskRunner : public base::TaskRunner {
 public:
  bool PostDelayedTask(const tracked_objects::Location& from_here,
                       const base::Closure& task,
                       base::TimeDelta delay) override {
    task.Run();
    return true;
  }
  bool RunsTasksOnCurrentThread() const override { return true; }

 protected:
  ~FakeTaskRunner() override {}
};

}  // namespace

class BlockingMethodCallerTest : public testing::Test {
 public:
  BlockingMethodCallerTest() : task_runner_(new FakeTaskRunner) {
  }

  void SetUp() override {
    // Create a mock bus.
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    mock_bus_ = new dbus::MockBus(options);

    // Create a mock proxy.
    mock_proxy_ = new dbus::MockObjectProxy(
        mock_bus_.get(),
        "org.chromium.TestService",
        dbus::ObjectPath("/org/chromium/TestObject"));

    // Set an expectation so mock_proxy's CallMethodAndBlock() will use
    // CreateMockProxyResponse() to return responses.
    EXPECT_CALL(*mock_proxy_.get(), MockCallMethodAndBlock(_, _))
        .WillRepeatedly(
             Invoke(this, &BlockingMethodCallerTest::CreateMockProxyResponse));

    // Set an expectation so mock_bus's GetObjectProxy() for the given
    // service name and the object path will return mock_proxy_.
    EXPECT_CALL(*mock_bus_.get(),
                GetObjectProxy("org.chromium.TestService",
                               dbus::ObjectPath("/org/chromium/TestObject")))
        .WillOnce(Return(mock_proxy_.get()));

    // Set an expectation so mock_bus's GetDBusTaskRunner will return the fake
    // task runner.
    EXPECT_CALL(*mock_bus_.get(), GetDBusTaskRunner())
        .WillRepeatedly(Return(task_runner_.get()));

    // ShutdownAndBlock() will be called in TearDown().
    EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
  }

  void TearDown() override { mock_bus_->ShutdownAndBlock(); }

 protected:
  scoped_refptr<FakeTaskRunner> task_runner_;
  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockObjectProxy> mock_proxy_;

 private:
  // Returns a response for the given method call. Used to implement
  // CallMethodAndBlock() for |mock_proxy_|.
  dbus::Response* CreateMockProxyResponse(dbus::MethodCall* method_call,
                                          int timeout_ms) {
    if (method_call->GetInterface() == "org.chromium.TestInterface" &&
        method_call->GetMember() == "Echo") {
      dbus::MessageReader reader(method_call);
      std::string text_message;
      if (reader.PopString(&text_message)) {
        std::unique_ptr<dbus::Response> response =
            dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        writer.AppendString(text_message);
        return response.release();
      }
    }

    LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
    return NULL;
  }
};

TEST_F(BlockingMethodCallerTest, Echo) {
  const char kHello[] = "Hello";
  // Get an object proxy from the mock bus.
  dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy(
      "org.chromium.TestService",
      dbus::ObjectPath("/org/chromium/TestObject"));

  // Create a method call.
  dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(kHello);

  // Call the method.
  BlockingMethodCaller blocking_method_caller(mock_bus_.get(), proxy);
  std::unique_ptr<dbus::Response> response(
      blocking_method_caller.CallMethodAndBlock(&method_call));

  // Check the response.
  ASSERT_TRUE(response.get());
  dbus::MessageReader reader(response.get());
  std::string text_message;
  ASSERT_TRUE(reader.PopString(&text_message));
  // The text message should be echo'ed back.
  EXPECT_EQ(kHello, text_message);
}

}  // namespace chromeos
