// 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/ibus/ibus_client.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/values.h"
#include "chromeos/dbus/ibus/ibus_constants.h"
#include "dbus/message.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h"
#include "dbus/values_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

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

namespace chromeos {

namespace {
const char kClientName[] = "chrome";
const char kEngineName[] = "engine";
const bool kRestartFlag = true;
}  // namespace

class MockCreateInputContextCallback {
 public:
  MOCK_METHOD1(Run, void(const dbus::ObjectPath& object_path));
};

class MockErrorCallback {
 public:
  MOCK_METHOD0(Run, void());
};

class IBusClientTest : public testing::Test {
 public:
  IBusClientTest() : response_(NULL) {}

  // Handles CreateInputContext method call.
  void OnCreateInputContext(
      dbus::MethodCall* method_call,
      int timeout_ms,
      const dbus::ObjectProxy::ResponseCallback& callback,
      const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    std::string client_name;
    EXPECT_TRUE(reader.PopString(&client_name));
    EXPECT_EQ(kClientName, client_name);
    EXPECT_FALSE(reader.HasMoreData());

    message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
  }

  // Handles fail case of CreateInputContext method call.
  void OnCreateInputContextFail(
      dbus::MethodCall* method_call,
      int timeout_ms,
      const dbus::ObjectProxy::ResponseCallback& callback,
      const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    std::string client_name;
    EXPECT_TRUE(reader.PopString(&client_name));
    EXPECT_EQ(kClientName, client_name);
    EXPECT_FALSE(reader.HasMoreData());

    message_loop_.PostTask(FROM_HERE, base::Bind(error_callback,
                                                 error_response_));
  }

  // Handles SetGlobalEngine method call.
  void OnSetGlobalEngine(
      dbus::MethodCall* method_call,
      int timeout_ms,
      const dbus::ObjectProxy::ResponseCallback& callback,
      const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    std::string engine_name;
    EXPECT_TRUE(reader.PopString(&engine_name));
    EXPECT_EQ(kEngineName, engine_name);
    EXPECT_FALSE(reader.HasMoreData());
    message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
  }

  // Handles fail case of SetGlobalEngine method call.
  void OnSetGlobalEngineFail(
      dbus::MethodCall* method_call,
      int timeout_ms,
      const dbus::ObjectProxy::ResponseCallback& callback,
      const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    std::string engine_name;
    EXPECT_TRUE(reader.PopString(&engine_name));
    EXPECT_EQ(kEngineName, engine_name);
    EXPECT_FALSE(reader.HasMoreData());
    message_loop_.PostTask(FROM_HERE, base::Bind(error_callback,
                                                 error_response_));
  }

  // Handles Exit method call.
  void OnExit(dbus::MethodCall* method_call,
              int timeout_ms,
              const dbus::ObjectProxy::ResponseCallback& callback,
              const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    bool restart = false;
    EXPECT_TRUE(reader.PopBool(&restart));
    EXPECT_EQ(kRestartFlag, restart);
    EXPECT_FALSE(reader.HasMoreData());
    message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
  }

  // Handles fail case of Exit method call.
  void OnExitFail(dbus::MethodCall* method_call,
                  int timeout_ms,
                  const dbus::ObjectProxy::ResponseCallback& callback,
                  const dbus::ObjectProxy::ErrorCallback& error_callback) {
    dbus::MessageReader reader(method_call);
    bool restart = false;
    EXPECT_TRUE(reader.PopBool(&restart));
    EXPECT_EQ(kRestartFlag, restart);
    EXPECT_FALSE(reader.HasMoreData());
    message_loop_.PostTask(FROM_HERE, base::Bind(error_callback,
                                                 error_response_));
  }

 protected:
  virtual void SetUp() OVERRIDE {
    dbus::Bus::Options options;
    mock_bus_ = new dbus::MockBus(options);
    mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(),
                                            ibus::kServiceName,
                                            dbus::ObjectPath(
                                                ibus::bus::kServicePath));
    EXPECT_CALL(*mock_bus_.get(),
                GetObjectProxy(ibus::kServiceName,
                               dbus::ObjectPath(ibus::bus::kServicePath)))
        .WillOnce(Return(mock_proxy_.get()));

    EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock());
    client_.reset(
        IBusClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, mock_bus_.get()));
  }

  virtual void TearDown() OVERRIDE {
    mock_bus_->ShutdownAndBlock();
  }

  // The IBus client to be tested.
  scoped_ptr<IBusClient> client_;

  // A message loop to emulate asynchronous behavior.
  base::MessageLoop message_loop_;
  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockObjectProxy> mock_proxy_;

  // Response returned by mock methods.
  dbus::Response* response_;
  dbus::ErrorResponse* error_response_;
};

TEST_F(IBusClientTest, CreateInputContextTest) {
  // Set expectations.
  const dbus::ObjectPath kInputContextObjectPath =
      dbus::ObjectPath("/some/object/path");
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext));
  MockCreateInputContextCallback callback;
  EXPECT_CALL(callback, Run(kInputContextObjectPath));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run()).Times(0);

  // Create response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  dbus::MessageWriter writer(response.get());
  writer.AppendObjectPath(kInputContextObjectPath);
  response_ = response.get();

  // Call CreateInputContext.
  client_->CreateInputContext(
      kClientName,
      base::Bind(&MockCreateInputContextCallback::Run,
                 base::Unretained(&callback)),
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, CreateInputContext_NullResponseFail) {
  // Set expectations.
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext));
  MockCreateInputContextCallback callback;
  EXPECT_CALL(callback, Run(_)).Times(0);
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Set NULL response.
  response_ = NULL;

  // Call CreateInputContext.
  client_->CreateInputContext(
      kClientName,
      base::Bind(&MockCreateInputContextCallback::Run,
                 base::Unretained(&callback)),
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, CreateInputContext_InvalidResponseFail) {
  // Set expectations.
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext));
  MockCreateInputContextCallback callback;
  EXPECT_CALL(callback, Run(_)).Times(0);
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Create invalid(empty) response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  response_ = response.get();

  // Call CreateInputContext.
  client_->CreateInputContext(
      kClientName,
      base::Bind(&MockCreateInputContextCallback::Run,
                 base::Unretained(&callback)),
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, CreateInputContext_MethodCallFail) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContextFail));
  MockCreateInputContextCallback callback;
  EXPECT_CALL(callback, Run(_)).Times(0);
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // The error response is not used in CreateInputContext.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->CreateInputContext(
      kClientName,
      base::Bind(&MockCreateInputContextCallback::Run,
                 base::Unretained(&callback)),
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, SetGlobalEngineTest) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngine));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run()).Times(0);

  // Create empty response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  response_ = response.get();

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->SetGlobalEngine(
      kEngineName,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, SetGlobalEngineTest_InvalidResponse) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Set invalid response.
  response_ = NULL;

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->SetGlobalEngine(
      kEngineName,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, SetGlobalEngineTest_MethodCallFail) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Create empty response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  response_ = response.get();

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->SetGlobalEngine(
      kEngineName,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, ExitTest) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnExit));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run()).Times(0);

  // Create empty response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  response_ = response.get();

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->Exit(
      IBusClient::RESTART_IBUS_DAEMON,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, ExitTest_InvalidResponse) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnExit));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Set invalid response.
  response_ = NULL;

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->Exit(
      IBusClient::RESTART_IBUS_DAEMON,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

TEST_F(IBusClientTest, ExitTest_MethodCallFail) {
  // Set expectations
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(Invoke(this, &IBusClientTest::OnExitFail));
  MockErrorCallback error_callback;
  EXPECT_CALL(error_callback, Run());

  // Create empty response.
  scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
  response_ = response.get();

  // The error response is not used in SetGLobalEngine.
  error_response_ = NULL;

  // Call CreateInputContext.
  client_->Exit(
      IBusClient::RESTART_IBUS_DAEMON,
      base::Bind(&MockErrorCallback::Run,
                 base::Unretained(&error_callback)));

  // Run the message loop.
  message_loop_.RunUntilIdle();
}

}  // namespace chromeos
