// Copyright 2015 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 "tpm_manager/client/tpm_ownership_dbus_proxy.h"

#include <string>
#include <utility>

#include <base/bind.h>
#include <brillo/dbus/dbus_param_writer.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "tpm_manager/client/mock_tpm_ownership_signal_handler.h"
#include "tpm_manager/common/tpm_ownership_dbus_interface.h"
#include "tpm_manager-client/tpm_manager/dbus-constants.h"

using testing::_;
using testing::Invoke;
using testing::SaveArg;
using testing::StrictMock;
using testing::WithArgs;

ACTION_TEMPLATE(MovePointee,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(pointer)) {
  *pointer = std::move(*(::std::get<k>(args)));
}

namespace tpm_manager {

class TpmOwnershipDBusProxyTest : public testing::Test {
 public:
  ~TpmOwnershipDBusProxyTest() override = default;
  void SetUp() override {
    mock_object_proxy_ = new StrictMock<dbus::MockObjectProxy>(
        nullptr, "", dbus::ObjectPath(kTpmManagerServicePath));
    proxy_.set_object_proxy(mock_object_proxy_.get());
  }

 protected:
  scoped_refptr<StrictMock<dbus::MockObjectProxy>> mock_object_proxy_;
  TpmOwnershipDBusProxy proxy_;
};

TEST_F(TpmOwnershipDBusProxyTest, ConnectToSignal) {
  MockTpmOwnershipTakenSignalHandler mock_signal_handler;
  // set up the signal here
  OwnershipTakenSignal expected_signal;
  OwnershipTakenSignal result_signal;
  expected_signal.mutable_local_data()->set_owner_password("owner password");
  expected_signal.mutable_local_data()->set_endorsement_password(
      "endorsement password");
  dbus::ObjectProxy::SignalCallback ownership_taken_callback;
  dbus::ObjectProxy::OnConnectedCallback signal_connected_callback;
  EXPECT_CALL(
      *mock_object_proxy_,
      DoConnectToSignal(kTpmOwnershipInterface, kOwnershipTakenSignal, _, _))
      .WillOnce(DoAll(SaveArg<2>(&ownership_taken_callback),
                      MovePointee<3>(&signal_connected_callback)));
  EXPECT_CALL(mock_signal_handler, OnOwnershipTaken(_))
      .WillOnce(SaveArg<0>(&result_signal));
  EXPECT_CALL(
      mock_signal_handler,
      OnSignalConnected(kTpmOwnershipInterface, kOwnershipTakenSignal, true))
      .Times(1);

  proxy_.ConnectToSignal(&mock_signal_handler);
  dbus::Signal signal(kTpmOwnershipInterface, kOwnershipTakenSignal);
  dbus::MessageWriter writer(&signal);
  brillo::dbus_utils::DBusParamWriter::Append(&writer, expected_signal);
  ownership_taken_callback.Run(&signal);
  std::move(signal_connected_callback)
      .Run(kTpmOwnershipInterface, kOwnershipTakenSignal, true);
  EXPECT_EQ(expected_signal.SerializeAsString(),
            result_signal.SerializeAsString());
}

TEST_F(TpmOwnershipDBusProxyTest, GetTpmStatus) {
  auto fake_dbus_call =
      [](dbus::MethodCall* method_call,
         dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        GetTpmStatusRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        GetTpmStatusReply reply;
        reply.set_status(STATUS_SUCCESS);
        reply.set_enabled(true);
        reply.set_owned(true);
        writer.AppendProtoAsArrayOfBytes(reply);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback = [](int* callback_count, const GetTpmStatusReply& reply) {
    (*callback_count)++;
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_TRUE(reply.enabled());
    EXPECT_TRUE(reply.owned());
  };
  GetTpmStatusRequest request;
  proxy_.GetTpmStatus(request, base::Bind(callback, &callback_count));
  EXPECT_EQ(1, callback_count);
}

TEST_F(TpmOwnershipDBusProxyTest, GetVersionInfo) {
  GetVersionInfoReply expected_version_info;
  expected_version_info.set_status(STATUS_SUCCESS);
  expected_version_info.set_family(1);
  expected_version_info.set_spec_level(2);
  expected_version_info.set_manufacturer(3);
  expected_version_info.set_tpm_model(4);
  expected_version_info.set_firmware_version(5);
  expected_version_info.set_vendor_specific("ab");

  auto fake_dbus_call =
      [&expected_version_info](
          dbus::MethodCall* method_call,
          dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        GetVersionInfoRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        writer.AppendProtoAsArrayOfBytes(expected_version_info);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback = [](const GetVersionInfoReply& expected_version_info,
                     int* callback_count,
                     const GetVersionInfoReply& actual_version_info) {
        (*callback_count)++;
        EXPECT_EQ(actual_version_info.SerializeAsString(),
                  expected_version_info.SerializeAsString());
      };
  GetVersionInfoRequest request;
  proxy_.GetVersionInfo(
      request, base::Bind(callback, expected_version_info, &callback_count));
  EXPECT_EQ(1, callback_count);
}

TEST_F(TpmOwnershipDBusProxyTest, GetDictionaryAttackInfo) {
  auto fake_dbus_call =
      [](dbus::MethodCall* method_call,
         dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        GetDictionaryAttackInfoRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        GetDictionaryAttackInfoReply reply;
        reply.set_status(STATUS_SUCCESS);
        reply.set_dictionary_attack_counter(3);
        reply.set_dictionary_attack_threshold(4);
        reply.set_dictionary_attack_lockout_in_effect(true);
        reply.set_dictionary_attack_lockout_seconds_remaining(5);
        writer.AppendProtoAsArrayOfBytes(reply);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback =
      [](int* callback_count, const GetDictionaryAttackInfoReply& reply) {
    (*callback_count)++;
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
    EXPECT_EQ(3, reply.dictionary_attack_counter());
    EXPECT_EQ(4, reply.dictionary_attack_threshold());
    EXPECT_TRUE(reply.dictionary_attack_lockout_in_effect());
    EXPECT_EQ(5, reply.dictionary_attack_lockout_seconds_remaining());
  };
  GetDictionaryAttackInfoRequest request;
  proxy_.GetDictionaryAttackInfo(
      request, base::Bind(callback, &callback_count));
  EXPECT_EQ(1, callback_count);
}

TEST_F(TpmOwnershipDBusProxyTest, TakeOwnership) {
  auto fake_dbus_call =
      [](dbus::MethodCall* method_call,
         dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        TakeOwnershipRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        TakeOwnershipReply reply;
        reply.set_status(STATUS_SUCCESS);
        writer.AppendProtoAsArrayOfBytes(reply);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback = [](int* callback_count, const TakeOwnershipReply& reply) {
    (*callback_count)++;
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
  };
  TakeOwnershipRequest request;
  proxy_.TakeOwnership(request, base::Bind(callback, &callback_count));
  EXPECT_EQ(1, callback_count);
}

TEST_F(TpmOwnershipDBusProxyTest, RemoveOwnerDependency) {
  const std::string owner_dependency("owner");
  auto fake_dbus_call =
      [&owner_dependency](
          dbus::MethodCall* method_call,
          dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        RemoveOwnerDependencyRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        EXPECT_TRUE(request.has_owner_dependency());
        EXPECT_EQ(owner_dependency, request.owner_dependency());
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        RemoveOwnerDependencyReply reply;
        reply.set_status(STATUS_SUCCESS);
        writer.AppendProtoAsArrayOfBytes(reply);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback = [](int* callback_count,
                     const RemoveOwnerDependencyReply& reply) {
    (*callback_count)++;
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
  };
  RemoveOwnerDependencyRequest request;
  request.set_owner_dependency(owner_dependency);
  proxy_.RemoveOwnerDependency(request, base::Bind(callback, &callback_count));
  EXPECT_EQ(1, callback_count);
}

TEST_F(TpmOwnershipDBusProxyTest, ClearStoredOwnerPassword) {
  auto fake_dbus_call =
      [](dbus::MethodCall* method_call,
         dbus::MockObjectProxy::ResponseCallback* response_callback) {
        // Verify request protobuf.
        dbus::MessageReader reader(method_call);
        ClearStoredOwnerPasswordRequest request;
        EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request));
        // Create reply protobuf.
        auto response = dbus::Response::CreateEmpty();
        dbus::MessageWriter writer(response.get());
        ClearStoredOwnerPasswordReply reply;
        reply.set_status(STATUS_SUCCESS);
        writer.AppendProtoAsArrayOfBytes(reply);
        std::move(*response_callback).Run(response.get());
      };
  EXPECT_CALL(*mock_object_proxy_, DoCallMethodWithErrorCallback(_, _, _, _))
      .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call)));

  // Set expectations on the outputs.
  int callback_count = 0;
  auto callback = [](int* callback_count,
                     const ClearStoredOwnerPasswordReply& reply) {
    (*callback_count)++;
    EXPECT_EQ(STATUS_SUCCESS, reply.status());
  };
  ClearStoredOwnerPasswordRequest request;
  proxy_.ClearStoredOwnerPassword(request,
                                  base::Bind(callback, &callback_count));
  EXPECT_EQ(1, callback_count);
}

}  // namespace tpm_manager
