// Copyright 2014 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 "buffet/commands/dbus_command_dispatcher.h"

#include <memory>
#include <string>

#include <chromeos/dbus/exported_object_manager.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <gtest/gtest.h>

#include "buffet/commands/command_dictionary.h"
#include "buffet/commands/command_queue.h"
#include "buffet/commands/unittest_utils.h"
#include "buffet/dbus_constants.h"

using buffet::unittests::CreateDictionaryValue;
using chromeos::dbus_utils::AsyncEventSequencer;
using testing::AnyNumber;
using testing::InSequence;
using testing::Invoke;
using testing::Return;
using testing::_;

namespace buffet {

namespace {
const char kCommandCategory[] = "test_category";

}  // anonymous namespace

class DBusCommandDispacherTest : public testing::Test {
 public:
  void SetUp() override {
    command_queue_.SetNowForTest(base::Time::Max());

    const dbus::ObjectPath kExportedObjectManagerPath("/test/om_path");
    std::string cmd_path = dbus_constants::kCommandServicePathPrefix;
    cmd_path += "1";
    const dbus::ObjectPath kCmdObjPath(cmd_path);

    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    bus_ = new dbus::MockBus(options);
    // By default, don't worry about threading assertions.
    EXPECT_CALL(*bus_, AssertOnOriginThread()).Times(AnyNumber());
    EXPECT_CALL(*bus_, AssertOnDBusThread()).Times(AnyNumber());
    // Use a mock exported object manager.
    mock_exported_object_manager_ = new dbus::MockExportedObject(
        bus_.get(), kExportedObjectManagerPath);
    EXPECT_CALL(*bus_, GetExportedObject(kExportedObjectManagerPath))
        .WillRepeatedly(Return(mock_exported_object_manager_.get()));
    EXPECT_CALL(*mock_exported_object_manager_,
                ExportMethod(_, _, _, _)).Times(AnyNumber());
    om_.reset(new chromeos::dbus_utils::ExportedObjectManager(
        bus_.get(), kExportedObjectManagerPath));
    om_->RegisterAsync(AsyncEventSequencer::GetDefaultCompletionAction());
    command_dispatcher_.reset(
        new DBusCommandDispacher(om_->GetBus(), om_.get()));
    command_queue_.SetCommandDispachInterface(command_dispatcher_.get());
    // Use a mock exported object for command proxy.
    mock_exported_command_proxy_ = new dbus::MockExportedObject(
        bus_.get(), kCmdObjPath);
    EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath))
        .WillRepeatedly(Return(mock_exported_command_proxy_.get()));
    EXPECT_CALL(*mock_exported_command_proxy_, ExportMethod(_, _, _, _))
        .WillRepeatedly(Invoke(MockExportMethod));

    auto json = CreateDictionaryValue(R"({
      'base': {
        'reboot': {
          'parameters': {'delay': 'integer'},
          'results': {}
        },
        'shutdown': {
          'parameters': {},
          'results': {}
        }
      }
    })");
    CHECK(dictionary_.LoadCommands(*json, kCommandCategory, nullptr, nullptr))
        << "Failed to load command dictionary";
  }

  void TearDown() override {
    EXPECT_CALL(*mock_exported_object_manager_, Unregister()).Times(1);
    om_.reset();
    bus_ = nullptr;
  }

  static void MockExportMethod(
      const std::string& interface_name,
      const std::string& method_name,
      dbus::ExportedObject::MethodCallCallback method_call_callback,
      dbus::ExportedObject::OnExportedCallback on_exported_callback) {
    on_exported_callback.Run(interface_name, method_name, true);
  }


  void AddNewCommand(const std::string& json, const std::string& id) {
    auto command_instance = CommandInstance::FromJson(
        CreateDictionaryValue(json.c_str()).get(), "cloud", dictionary_,
        nullptr);
    command_instance->SetID(id);
    // Two interfaces are added - Command and Properties.
    EXPECT_CALL(*mock_exported_object_manager_, SendSignal(_)).Times(2);
    command_queue_.Add(std::move(command_instance));
  }

  DBusCommandProxy* FindProxy(CommandInstance* command_instance) {
    CHECK_EQ(command_instance->proxies_.size(), 1U);
    return static_cast<DBusCommandProxy*>(command_instance->proxies_[0].get());
  }

  void FinishCommand(DBusCommandProxy* proxy) {
    proxy->Done();
  }

  void SetProgress(DBusCommandProxy* proxy, int progress) {
    proxy->SetProgress(nullptr, progress);
  }


  scoped_refptr<dbus::MockBus> bus_;
  scoped_refptr<dbus::MockExportedObject> mock_exported_object_manager_;
  scoped_refptr<dbus::MockExportedObject> mock_exported_command_proxy_;
  std::unique_ptr<chromeos::dbus_utils::ExportedObjectManager> om_;
  CommandDictionary dictionary_;
  CommandQueue command_queue_;
  std::unique_ptr<DBusCommandDispacher> command_dispatcher_;
};

TEST_F(DBusCommandDispacherTest, Test_Command_Base_Shutdown) {
  const std::string id = "id0000";
  AddNewCommand("{'name':'base.shutdown'}", id);
  CommandInstance* command_instance = command_queue_.Find(id);
  ASSERT_NE(nullptr, command_instance);
  DBusCommandProxy* command_proxy = FindProxy(command_instance);
  ASSERT_NE(nullptr, command_proxy);
  EXPECT_EQ(CommandInstance::kStatusQueued, command_instance->GetStatus());

  // Two properties are set, Progress = 50%, Status = "inProgress"
  EXPECT_CALL(*mock_exported_command_proxy_, SendSignal(_)).Times(2);
  SetProgress(command_proxy, 50);
  EXPECT_EQ(CommandInstance::kStatusInProgress, command_instance->GetStatus());
  EXPECT_EQ(50, command_instance->GetProgress());

  // Command must be removed from the queue and proxy destroyed after calling
  // FinishCommand().
  // Two properties are set, Progress = 100%, Status = "done"
  EXPECT_CALL(*mock_exported_command_proxy_, SendSignal(_)).Times(2);
  // D-Bus command proxy is going away.
  EXPECT_CALL(*mock_exported_command_proxy_, Unregister()).Times(1);
  // Two interfaces are being removed on the D-Bus command object.
  EXPECT_CALL(*mock_exported_object_manager_, SendSignal(_)).Times(2);
  FinishCommand(command_proxy);

  EXPECT_EQ(nullptr, command_queue_.Find(id));
}

TEST_F(DBusCommandDispacherTest, Test_Command_Base_Reboot) {
  const std::string id = "id0001";
  AddNewCommand(R"({
    'name': 'base.reboot',
    'parameters': {
      'delay': 20
    }
  })", id);
  CommandInstance* command_instance = command_queue_.Find(id);
  ASSERT_NE(nullptr, command_instance);
  DBusCommandProxy* command_proxy = FindProxy(command_instance);
  ASSERT_NE(nullptr, command_proxy);
  EXPECT_EQ(CommandInstance::kStatusQueued, command_instance->GetStatus());

  // Two properties are set, Progress = 50%, Status = "inProgress"
  EXPECT_CALL(*mock_exported_command_proxy_, SendSignal(_)).Times(2);
  SetProgress(command_proxy, 50);
  EXPECT_EQ(CommandInstance::kStatusInProgress, command_instance->GetStatus());
  EXPECT_EQ(50, command_instance->GetProgress());

  // Command must be removed from the queue and proxy destroyed after calling
  // FinishCommand().
  // Two properties are set, Progress = 100%, Status = "done"
  EXPECT_CALL(*mock_exported_command_proxy_, SendSignal(_)).Times(2);
  // D-Bus command proxy is going away.
  EXPECT_CALL(*mock_exported_command_proxy_, Unregister()).Times(1);
  // Two interfaces are being removed on the D-Bus command object.
  EXPECT_CALL(*mock_exported_object_manager_, SendSignal(_)).Times(2);
  FinishCommand(command_proxy);

  EXPECT_EQ(nullptr, command_queue_.Find(id));
}


}  // namespace buffet
