//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <string>

#include <base/bind.h>
#include <brillo/dbus/dbus_object_test_helpers.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <tpm_manager-client/tpm_manager/dbus-constants.h>

#include "tpm_manager/common/mock_tpm_nvram_interface.h"
#include "tpm_manager/common/mock_tpm_ownership_interface.h"
#include "tpm_manager/common/tpm_nvram_dbus_interface.h"
#include "tpm_manager/common/tpm_ownership_dbus_interface.h"
#include "tpm_manager/server/dbus_service.h"
#include "tpm_manager/server/mock_local_data_store.h"

using testing::_;
using testing::Invoke;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
using testing::WithArgs;

namespace tpm_manager {

class DBusServiceTest : public testing::Test {
 public:
  ~DBusServiceTest() override = default;
  void SetUp() override {
    dbus::Bus::Options options;
    mock_bus_ = new NiceMock<dbus::MockBus>(options);
    dbus::ObjectPath path(kTpmManagerServicePath);
    mock_exported_object_ =
        new NiceMock<dbus::MockExportedObject>(mock_bus_.get(), path);
    ON_CALL(*mock_bus_, GetExportedObject(path))
        .WillByDefault(Return(mock_exported_object_.get()));
    dbus_service_.reset(new DBusService(mock_bus_, &mock_nvram_service_,
                                        &mock_ownership_service_,
                                        &mock_data_store_));
  }

  void RegisterDBusObjectsAsync() {
    scoped_refptr<brillo::dbus_utils::AsyncEventSequencer> sequencer(
        new brillo::dbus_utils::AsyncEventSequencer());
    dbus_service_->RegisterDBusObjectsAsync(sequencer.get());
  }

  template <typename RequestProtobufType, typename ReplyProtobufType>
  void ExecuteMethod(const std::string& method_name,
                     const RequestProtobufType& request,
                     ReplyProtobufType* reply,
                     const std::string& interface) {
    std::unique_ptr<dbus::MethodCall> call =
        CreateMethodCall(method_name, interface);
    dbus::MessageWriter writer(call.get());
    writer.AppendProtoAsArrayOfBytes(request);
    auto response = brillo::dbus_utils::testing::CallMethod(
        *dbus_service_->dbus_object_, call.get());
    dbus::MessageReader reader(response.get());
    EXPECT_TRUE(reader.PopArrayOfBytesAsProto(reply));
  }

 protected:
  std::unique_ptr<dbus::MethodCall> CreateMethodCall(
      const std::string& method_name,
      const std::string& interface) {
    std::unique_ptr<dbus::MethodCall> call(
        new dbus::MethodCall(interface, method_name));
    call->SetSerial(1);
    return call;
  }

  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
  StrictMock<MockLocalDataStore> mock_data_store_;
  StrictMock<MockTpmNvramInterface> mock_nvram_service_;
  StrictMock<MockTpmOwnershipInterface> mock_ownership_service_;
  std::unique_ptr<DBusService> dbus_service_;
};

TEST_F(DBusServiceTest, CopyableCallback) {
  RegisterDBusObjectsAsync();

  EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
      .WillOnce(WithArgs<1>(Invoke(
          [](const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
            // Copy the callback, then call the original.
            GetTpmStatusReply reply;
            base::Closure copy = base::Bind(callback, reply);
            callback.Run(reply);
          })));
  GetTpmStatusRequest request;
  GetTpmStatusReply reply;
  ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
}

TEST_F(DBusServiceTest, GetTpmStatus) {
  RegisterDBusObjectsAsync();

  GetTpmStatusRequest request;
  EXPECT_CALL(mock_ownership_service_, GetTpmStatus(_, _))
      .WillOnce(Invoke(
          [](const GetTpmStatusRequest& request,
             const TpmOwnershipInterface::GetTpmStatusCallback& callback) {
            GetTpmStatusReply reply;
            reply.set_status(STATUS_SUCCESS);
            reply.set_enabled(true);
            reply.set_owned(true);
            callback.Run(reply);
          }));
  GetTpmStatusReply reply;
  ExecuteMethod(kGetTpmStatus, request, &reply, kTpmOwnershipInterface);
  EXPECT_EQ(STATUS_SUCCESS, reply.status());
  EXPECT_TRUE(reply.enabled());
  EXPECT_TRUE(reply.owned());
}

TEST_F(DBusServiceTest, GetDictionaryAttackInfo) {
  RegisterDBusObjectsAsync();

  GetDictionaryAttackInfoRequest request;
  EXPECT_CALL(mock_ownership_service_, GetDictionaryAttackInfo(_, _))
      .WillOnce(Invoke(
          [](const GetDictionaryAttackInfoRequest& request,
             const TpmOwnershipInterface::GetDictionaryAttackInfoCallback&
                 callback) {
            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);
            callback.Run(reply);
          }));
  GetDictionaryAttackInfoReply reply;
  ExecuteMethod(
      kGetDictionaryAttackInfo, request, &reply, kTpmOwnershipInterface);
  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());
}

TEST_F(DBusServiceTest, ResetDictionaryAttackLock) {
  RegisterDBusObjectsAsync();

  ResetDictionaryAttackLockRequest request;
  EXPECT_CALL(mock_ownership_service_, ResetDictionaryAttackLock(_, _))
      .WillOnce(Invoke(
          [](const ResetDictionaryAttackLockRequest& request,
             const TpmOwnershipInterface::ResetDictionaryAttackLockCallback&
                 callback) {
            ResetDictionaryAttackLockReply reply;
            reply.set_status(STATUS_SUCCESS);
            callback.Run(reply);
          }));
  ResetDictionaryAttackLockReply reply;
  ExecuteMethod(
      kResetDictionaryAttackLock, request, &reply, kTpmOwnershipInterface);
  EXPECT_EQ(STATUS_SUCCESS, reply.status());
}

TEST_F(DBusServiceTest, TakeOwnership) {
  RegisterDBusObjectsAsync();

  EXPECT_CALL(mock_ownership_service_, TakeOwnership(_, _))
      .WillOnce(Invoke(
          [](const TakeOwnershipRequest& request,
             const TpmOwnershipInterface::TakeOwnershipCallback& callback) {
            TakeOwnershipReply reply;
            reply.set_status(STATUS_SUCCESS);
            callback.Run(reply);
          }));
  TakeOwnershipRequest request;
  TakeOwnershipReply reply;
  ExecuteMethod(kTakeOwnership, request, &reply, kTpmOwnershipInterface);
  EXPECT_EQ(STATUS_SUCCESS, reply.status());
}

TEST_F(DBusServiceTest, RemoveOwnerDependency) {
  RegisterDBusObjectsAsync();

  std::string owner_dependency("owner_dependency");
  RemoveOwnerDependencyRequest request;
  request.set_owner_dependency(owner_dependency);
  EXPECT_CALL(mock_ownership_service_, RemoveOwnerDependency(_, _))
      .WillOnce(Invoke([&owner_dependency](
          const RemoveOwnerDependencyRequest& request,
          const TpmOwnershipInterface::RemoveOwnerDependencyCallback&
              callback) {
        EXPECT_TRUE(request.has_owner_dependency());
        EXPECT_EQ(owner_dependency, request.owner_dependency());
        RemoveOwnerDependencyReply reply;
        reply.set_status(STATUS_SUCCESS);
        callback.Run(reply);
      }));
  RemoveOwnerDependencyReply reply;
  ExecuteMethod(kRemoveOwnerDependency, request, &reply,
                kTpmOwnershipInterface);
  EXPECT_EQ(STATUS_SUCCESS, reply.status());
}

TEST_F(DBusServiceTest, ClearStoredOwnerPassword) {
  RegisterDBusObjectsAsync();

  ClearStoredOwnerPasswordRequest request;
  EXPECT_CALL(mock_ownership_service_, ClearStoredOwnerPassword(_, _))
      .WillOnce(Invoke([](
          const ClearStoredOwnerPasswordRequest& request,
          const TpmOwnershipInterface::ClearStoredOwnerPasswordCallback&
              callback) {
        ClearStoredOwnerPasswordReply reply;
        reply.set_status(STATUS_SUCCESS);
        callback.Run(reply);
      }));
  ClearStoredOwnerPasswordReply reply;
  ExecuteMethod(kClearStoredOwnerPassword, request, &reply,
                kTpmOwnershipInterface);
  EXPECT_EQ(STATUS_SUCCESS, reply.status());
}

TEST_F(DBusServiceTest, DefineSpace) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  size_t nvram_length = 32;
  DefineSpaceRequest request;
  request.set_index(nvram_index);
  request.set_size(nvram_length);
  EXPECT_CALL(mock_nvram_service_, DefineSpace(_, _))
      .WillOnce(Invoke([nvram_index, nvram_length](
          const DefineSpaceRequest& request,
          const TpmNvramInterface::DefineSpaceCallback& callback) {
        EXPECT_TRUE(request.has_index());
        EXPECT_EQ(nvram_index, request.index());
        EXPECT_TRUE(request.has_size());
        EXPECT_EQ(nvram_length, request.size());
        DefineSpaceReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        callback.Run(reply);
      }));
  DefineSpaceReply reply;
  ExecuteMethod(kDefineSpace, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
}

TEST_F(DBusServiceTest, DestroySpace) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  DestroySpaceRequest request;
  request.set_index(nvram_index);
  EXPECT_CALL(mock_nvram_service_, DestroySpace(_, _))
      .WillOnce(Invoke([nvram_index](
          const DestroySpaceRequest& request,
          const TpmNvramInterface::DestroySpaceCallback& callback) {
        EXPECT_TRUE(request.has_index());
        EXPECT_EQ(nvram_index, request.index());
        DestroySpaceReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        callback.Run(reply);
      }));
  DestroySpaceReply reply;
  ExecuteMethod(kDestroySpace, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
}

TEST_F(DBusServiceTest, WriteSpace) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  std::string nvram_data("nvram_data");
  WriteSpaceRequest request;
  request.set_index(nvram_index);
  request.set_data(nvram_data);
  EXPECT_CALL(mock_nvram_service_, WriteSpace(_, _))
      .WillOnce(Invoke([nvram_index, nvram_data](
          const WriteSpaceRequest& request,
          const TpmNvramInterface::WriteSpaceCallback& callback) {
        EXPECT_TRUE(request.has_index());
        EXPECT_EQ(nvram_index, request.index());
        EXPECT_TRUE(request.has_data());
        EXPECT_EQ(nvram_data, request.data());
        WriteSpaceReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        callback.Run(reply);
      }));
  WriteSpaceReply reply;
  ExecuteMethod(kWriteSpace, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
}

TEST_F(DBusServiceTest, ReadSpace) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  std::string nvram_data("nvram_data");
  ReadSpaceRequest request;
  request.set_index(nvram_index);
  EXPECT_CALL(mock_nvram_service_, ReadSpace(_, _))
      .WillOnce(Invoke([nvram_index, nvram_data](
          const ReadSpaceRequest& request,
          const TpmNvramInterface::ReadSpaceCallback& callback) {
        EXPECT_TRUE(request.has_index());
        EXPECT_EQ(nvram_index, request.index());
        ReadSpaceReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        reply.set_data(nvram_data);
        callback.Run(reply);
      }));
  ReadSpaceReply reply;
  ExecuteMethod(kReadSpace, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
  EXPECT_TRUE(reply.has_data());
  EXPECT_EQ(nvram_data, reply.data());
}

TEST_F(DBusServiceTest, LockSpace) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  LockSpaceRequest request;
  request.set_index(nvram_index);
  request.set_lock_read(true);
  request.set_lock_write(true);
  EXPECT_CALL(mock_nvram_service_, LockSpace(_, _))
      .WillOnce(Invoke(
          [nvram_index](const LockSpaceRequest& request,
                        const TpmNvramInterface::LockSpaceCallback& callback) {
            EXPECT_TRUE(request.has_index());
            EXPECT_EQ(nvram_index, request.index());
            EXPECT_TRUE(request.lock_read());
            EXPECT_TRUE(request.lock_write());
            LockSpaceReply reply;
            reply.set_result(NVRAM_RESULT_SUCCESS);
            callback.Run(reply);
          }));
  LockSpaceReply reply;
  ExecuteMethod(kLockSpace, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
}

TEST_F(DBusServiceTest, ListSpaces) {
  RegisterDBusObjectsAsync();

  constexpr uint32_t nvram_index_list[] = {3, 4, 5};
  ListSpacesRequest request;
  EXPECT_CALL(mock_nvram_service_, ListSpaces(_, _))
      .WillOnce(Invoke([nvram_index_list](
          const ListSpacesRequest& request,
          const TpmNvramInterface::ListSpacesCallback& callback) {
        ListSpacesReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        for (auto index : nvram_index_list) {
          reply.add_index_list(index);
        }
        callback.Run(reply);
      }));
  ListSpacesReply reply;
  ExecuteMethod(kListSpaces, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
  EXPECT_EQ(arraysize(nvram_index_list), reply.index_list_size());
  for (size_t i = 0; i < 3; i++) {
    EXPECT_EQ(nvram_index_list[i], reply.index_list(i));
  }
}

TEST_F(DBusServiceTest, GetSpaceInfo) {
  RegisterDBusObjectsAsync();

  uint32_t nvram_index = 5;
  size_t nvram_size = 32;
  GetSpaceInfoRequest request;
  request.set_index(nvram_index);
  EXPECT_CALL(mock_nvram_service_, GetSpaceInfo(_, _))
      .WillOnce(Invoke([nvram_index, nvram_size](
          const GetSpaceInfoRequest& request,
          const TpmNvramInterface::GetSpaceInfoCallback& callback) {
        EXPECT_TRUE(request.has_index());
        EXPECT_EQ(nvram_index, request.index());
        GetSpaceInfoReply reply;
        reply.set_result(NVRAM_RESULT_SUCCESS);
        reply.set_size(nvram_size);
        reply.set_is_read_locked(true);
        reply.set_is_write_locked(true);
        callback.Run(reply);
      }));
  GetSpaceInfoReply reply;
  ExecuteMethod(kGetSpaceInfo, request, &reply, kTpmNvramInterface);
  EXPECT_EQ(NVRAM_RESULT_SUCCESS, reply.result());
  EXPECT_TRUE(reply.has_size());
  EXPECT_EQ(nvram_size, reply.size());
  EXPECT_TRUE(reply.is_read_locked());
  EXPECT_TRUE(reply.is_write_locked());
}

TEST_F(DBusServiceTest, SendOwnershipTakenSignalAfterNotification) {
  RegisterDBusObjectsAsync();

  EXPECT_FALSE(dbus_service_->MaybeSendOwnershipTakenSignal());
  dbus_service_->NotifyOwnershipIsTaken();
  EXPECT_TRUE(dbus_service_->MaybeSendOwnershipTakenSignal());
}

TEST_F(DBusServiceTest, SendOwnershipTakenSignalError) {
  ON_CALL(*mock_bus_, GetExportedObject(_)).WillByDefault(Return(nullptr));

  RegisterDBusObjectsAsync();
  dbus_service_->NotifyOwnershipIsTaken();

  EXPECT_FALSE(dbus_service_->MaybeSendOwnershipTakenSignal());
}

TEST_F(DBusServiceTest, SendOwnershipTakenSignalAfterRegistration) {
  dbus_service_->NotifyOwnershipIsTaken();
  EXPECT_FALSE(dbus_service_->MaybeSendOwnershipTakenSignal());

  RegisterDBusObjectsAsync();

  EXPECT_TRUE(dbus_service_->MaybeSendOwnershipTakenSignal());
}

}  // namespace tpm_manager
