// 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 <functional>
#include <memory>

#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/property.h>
#include <chromeos/dbus/dbus_object.h>
#include <gtest/gtest.h>

#include "buffet/commands/command_dictionary.h"
#include "buffet/commands/command_instance.h"
#include "buffet/commands/dbus_command_proxy.h"
#include "buffet/commands/unittest_utils.h"
#include "buffet/dbus_constants.h"

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

using chromeos::dbus_utils::ExportedObjectManager;
using buffet::unittests::CreateDictionaryValue;

namespace buffet {

namespace {

const char kTestCommandCategoty[] = "test_command_category";
const char kTestCommandId[] = "cmd_1";

void NoAction(bool all_succeeded) {}

}  // namespace

class DBusCommandProxyTest : public ::testing::Test {
 public:
  void SetUp() override {
    // Set up a mock DBus bus object.
    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());

    // Command instance.
    auto json = CreateDictionaryValue(R"({
      'robot': {
        'jump': {
          'parameters': {
            'height': {
              'type': 'integer',
              'minimum': 0,
              'maximum': 100
            },
            '_jumpType': {
              'type': 'string',
              'enum': ['_withAirFlip', '_withSpin', '_withKick']
            }
          }
        }
      }
    })");
    CHECK(dict_.LoadCommands(*json, kTestCommandCategoty, nullptr, nullptr))
        << "Failed to parse test command dictionary";

    json = CreateDictionaryValue(R"({
      'name': 'robot.jump',
      'parameters': {
        'height': 53,
        '_jumpType': '_withKick'
      }
    })");
    command_instance_ = CommandInstance::FromJson(json.get(), dict_, nullptr);
    command_instance_->SetID(kTestCommandId);

    // Set up a mock ExportedObject to be used with the DBus command proxy.
    std::string cmd_path = dbus_constants::kCommandServicePathPrefix;
    cmd_path += kTestCommandId;
    const dbus::ObjectPath kCmdObjPath(cmd_path);
    // Use a mock exported object for the exported object manager.
    mock_exported_object_command_ =
        new dbus::MockExportedObject(bus_.get(), kCmdObjPath);
    EXPECT_CALL(*bus_, GetExportedObject(kCmdObjPath)).Times(AnyNumber())
        .WillRepeatedly(Return(mock_exported_object_command_.get()));
    EXPECT_CALL(*mock_exported_object_command_,
                ExportMethod(_, _, _, _)).Times(AnyNumber());

    command_proxy_.reset(new DBusCommandProxy(nullptr, bus_,
                                              command_instance_.get()));
    command_proxy_->RegisterAsync(base::Bind(NoAction));
  }

  void TearDown() override {
    EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1);
    command_proxy_.reset();
    command_instance_.reset();
    dict_.Clear();
    bus_ = nullptr;
  }

  chromeos::dbus_utils::DBusObject* GetProxyDBusObject() {
    return &command_proxy_->dbus_object_;
  }

  std::string GetStatus() const {
    return command_proxy_->status_.value();
  }

  int32_t GetProgress() const {
    return command_proxy_->progress_.value();
  }

  std::unique_ptr<dbus::Response> CallMethod(
      const std::string& method_name,
      const std::function<void(dbus::MessageWriter*)>& param_callback) {
    dbus::MethodCall method_call(dbus_constants::kCommandInterface,
                                 method_name);
    method_call.SetSerial(1234);
    dbus::MessageWriter writer(&method_call);
    if (param_callback)
      param_callback(&writer);
    return chromeos::dbus_utils::CallMethod(*GetProxyDBusObject(),
                                            &method_call);
  }

  static bool IsResponseError(const std::unique_ptr<dbus::Response>& response) {
    return (response->GetMessageType() == dbus::Message::MESSAGE_ERROR);
  }

  static void VerifyResponse(
      const std::unique_ptr<dbus::Response>& response,
      const std::function<void(dbus::MessageReader*)>& result_callback) {
    EXPECT_FALSE(IsResponseError(response));
    dbus::MessageReader reader(response.get());
    if (result_callback)
      result_callback(&reader);
    EXPECT_FALSE(reader.HasMoreData());
  }

  template<typename T>
  T GetPropertyValue(const std::string& property_name) {
    dbus::MethodCall method_call(dbus::kPropertiesInterface,
                                 dbus::kPropertiesGet);
    method_call.SetSerial(1234);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(dbus_constants::kCommandInterface);
    writer.AppendString(property_name);
    auto response = chromeos::dbus_utils::CallMethod(*GetProxyDBusObject(),
                                                     &method_call);
    T value{};
    VerifyResponse(response, [&value](dbus::MessageReader* reader) {
      EXPECT_TRUE(chromeos::dbus_utils::PopValueFromReader(reader, &value));
    });
    return value;
  }

  std::unique_ptr<DBusCommandProxy> command_proxy_;
  std::unique_ptr<CommandInstance> command_instance_;
  CommandDictionary dict_;

  scoped_refptr<dbus::MockExportedObject> mock_exported_object_command_;
  scoped_refptr<dbus::MockBus> bus_;
};

TEST_F(DBusCommandProxyTest, Init) {
  EXPECT_EQ(dbus_constants::kCommandStatusQueued, GetStatus());
  EXPECT_EQ(0, GetProgress());
  EXPECT_EQ("robot.jump",
            GetPropertyValue<std::string>(dbus_constants::kCommandName));
  EXPECT_EQ(kTestCommandCategoty,
            GetPropertyValue<std::string>(dbus_constants::kCommandCategory));
  EXPECT_EQ(kTestCommandId,
            GetPropertyValue<std::string>(dbus_constants::kCommandId));
  EXPECT_EQ(dbus_constants::kCommandStatusQueued,
            GetPropertyValue<std::string>(dbus_constants::kCommandStatus));
  EXPECT_EQ(0, GetPropertyValue<int32_t>(dbus_constants::kCommandProgress));
}

TEST_F(DBusCommandProxyTest, SetProgress) {
  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(2);
  auto response = CallMethod(dbus_constants::kCommandSetProgress,
                             [](dbus::MessageWriter* writer) {
    writer->AppendInt32(10);
  });
  VerifyResponse(response, {});
  EXPECT_EQ(dbus_constants::kCommandStatusInProgress, GetStatus());
  EXPECT_EQ(10, GetProgress());
  EXPECT_EQ(dbus_constants::kCommandStatusInProgress,
            GetPropertyValue<std::string>(dbus_constants::kCommandStatus));
  EXPECT_EQ(10, GetPropertyValue<int32_t>(dbus_constants::kCommandProgress));
}

TEST_F(DBusCommandProxyTest, SetProgress_OutOfRange) {
  auto response = CallMethod(dbus_constants::kCommandSetProgress,
                             [](dbus::MessageWriter* writer) {
    writer->AppendInt32(110);
  });
  EXPECT_TRUE(IsResponseError(response));
  EXPECT_EQ(dbus_constants::kCommandStatusQueued, GetStatus());
  EXPECT_EQ(0, GetProgress());
}

TEST_F(DBusCommandProxyTest, Abort) {
  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
  auto response = CallMethod(dbus_constants::kCommandAbort, {});
  VerifyResponse(response, {});
  EXPECT_EQ(dbus_constants::kCommandStatusAborted, GetStatus());
}

TEST_F(DBusCommandProxyTest, Cancel) {
  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(1);
  auto response = CallMethod(dbus_constants::kCommandCancel, {});
  VerifyResponse(response, {});
  EXPECT_EQ(dbus_constants::kCommandStatusCanceled, GetStatus());
}

TEST_F(DBusCommandProxyTest, Done) {
  EXPECT_CALL(*mock_exported_object_command_, SendSignal(_)).Times(2);
  auto response = CallMethod(dbus_constants::kCommandDone, {});
  VerifyResponse(response, {});
  EXPECT_EQ(dbus_constants::kCommandStatusDone, GetStatus());
  EXPECT_EQ(100, GetProgress());
}

}  // namespace buffet
