// Copyright 2019 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 "login_manager/arc_sideload_status.h"

#include <memory>

#include <chromeos/dbus/service_constants.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "bootlockbox/proto_bindings/boot_lockbox_rpc.pb.h"
#include "login_manager/dbus_test_util.h"

using ::testing::_;

namespace login_manager {

ACTION_TEMPLATE(RunCallback,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(p0)) {
  return ::testing::get<k>(args).Run(p0);
}

#define EXPECT_DBUS_CALL_THEN_CALLBACK(method_call, response)  \
  EXPECT_CALL(*boot_lockbox_proxy_,                            \
              CallMethod(DBusMethodCallEq(method_call), _, _)) \
      .WillOnce(RunCallback<2>(response));

void EnableCallbackAdaptor(ArcSideloadStatusInterface::Status* status,
                           char** error,
                           ArcSideloadStatusInterface::Status s,
                           const char* e) {
  *status = s;
  *error = const_cast<char*>(e);
}

void QueryCallbackAdaptor(ArcSideloadStatusInterface::Status* status,
                          ArcSideloadStatusInterface::Status s) {
  *status = s;
}

class ArcSideloadStatusTest : public ::testing::Test {
 public:
  ArcSideloadStatusTest()
      : boot_lockbox_proxy_(
            new dbus::MockObjectProxy(nullptr, "", dbus::ObjectPath(""))),
        bootlockbox_read_method_call_(cryptohome::kBootLockboxInterface,
                                      cryptohome::kBootLockboxReadBootLockbox),
        bootlockbox_store_method_call_(
            cryptohome::kBootLockboxInterface,
            cryptohome::kBootLockboxStoreBootLockbox) {}

  ~ArcSideloadStatusTest() override {}

  void SetUp() override {
    arc_sideload_status_ =
        std::make_unique<ArcSideloadStatus>(boot_lockbox_proxy_.get());
  }

 protected:
  bool ParseBoolResponse(dbus::Response* response) {
    bool value;
    dbus::MessageReader reader(response);
    EXPECT_TRUE(reader.PopBool(&value));
    EXPECT_FALSE(reader.HasMoreData());
    return value;
  }

  void ExpectBootLockboxServiceToBeAvailable(bool available) {
    EXPECT_CALL(*boot_lockbox_proxy_, WaitForServiceToBeAvailable(_))
        .WillOnce(RunCallback<0>(available));
  }

  void PretendInitialized() {
    arc_sideload_status_->OverrideAdbSideloadStatusTestOnly(
        true /* not really used */);
  }

  // Returns a valid query response containing the given value in bootlockbox.
  std::unique_ptr<dbus::Response> CreateValidQueryResponse(bool enabled) {
    auto bootlockbox_response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(bootlockbox_response.get());
    cryptohome::BootLockboxBaseReply reply;
    reply.MutableExtension(cryptohome::ReadBootLockboxReply::reply)
        ->set_data(enabled ? "1" : "0");
    EXPECT_TRUE(writer.AppendProtoAsArrayOfBytes(reply));
    return bootlockbox_response;
  }

  // Returns a valid response containing a bootlockbox error.
  std::unique_ptr<dbus::Response> CreateResponseWithBootLockboxError(
      cryptohome::BootLockboxErrorCode error_code) {
    auto bootlockbox_response = dbus::Response::CreateEmpty();
    dbus::MessageWriter writer(bootlockbox_response.get());
    cryptohome::BootLockboxBaseReply base_reply;
    base_reply.set_error(error_code);
    EXPECT_TRUE(writer.AppendProtoAsArrayOfBytes(base_reply));
    return bootlockbox_response;
  }

  static ArcSideloadStatusInterface::QueryAdbSideloadCallback
  CaptureQueryCallback(ArcSideloadStatusInterface::Status* status) {
    return base::Bind(&QueryCallbackAdaptor, status);
  }

  static ArcSideloadStatusInterface::EnableAdbSideloadCallback
  CaptureEnableCallback(ArcSideloadStatusInterface::Status* sideload_status,
                        char** error) {
    return base::Bind(&EnableCallbackAdaptor, sideload_status, error);
  }

  scoped_refptr<dbus::MockObjectProxy> boot_lockbox_proxy_;
  std::unique_ptr<ArcSideloadStatus> arc_sideload_status_;
  dbus::MethodCall bootlockbox_read_method_call_;
  dbus::MethodCall bootlockbox_store_method_call_;
};

TEST_F(ArcSideloadStatusTest, IsAdbSideloadAllowed_Default) {
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, Initialize_ServiceNotAvailable) {
  ExpectBootLockboxServiceToBeAvailable(false);
  arc_sideload_status_->Initialize();
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
  // Expect nothing else.
}

TEST_F(ArcSideloadStatusTest, InitializeThenQueryAdbSideload) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = CreateValidQueryResponse(true);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->Initialize();
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::ENABLED);
  EXPECT_TRUE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, QueryAdbSideloadThenInitialize) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = CreateValidQueryResponse(true);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));
  arc_sideload_status_->Initialize();

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::ENABLED);
  EXPECT_TRUE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, QueryAdbSideload_NeedPowerwash) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = dbus::Response::CreateEmpty();
  {
    dbus::MessageWriter writer(bootlockbox_response.get());
    cryptohome::BootLockboxBaseReply reply;
    reply.set_error(cryptohome::BOOTLOCKBOX_ERROR_NVSPACE_UNDEFINED);
    EXPECT_TRUE(writer.AppendProtoAsArrayOfBytes(reply));
  }
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->Initialize();
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::NEED_POWERWASH);
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, QueryAdbSideloadThenBadInitialize) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(false);

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));
  arc_sideload_status_->Initialize();

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, MultipleQueryAdbSideloadThenInitialize) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = CreateValidQueryResponse(true);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status1;
  ArcSideloadStatusInterface::Status status2;
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status1));
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status2));
  arc_sideload_status_->Initialize();

  // Verify
  EXPECT_EQ(status1, ArcSideloadStatusInterface::Status::ENABLED);
  EXPECT_EQ(status2, ArcSideloadStatusInterface::Status::ENABLED);
  EXPECT_TRUE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, InitializeThenQueryAdbSideload_NullResponse) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_, nullptr);

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->Initialize();
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, InitializeThenQueryAdbSideload_BadFormat) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = dbus::Response::CreateEmpty();
  dbus::MessageWriter writer(bootlockbox_response.get());
  writer.AppendString("garbage");
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->Initialize();
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, InitializeThenQueryAdbSideload_MissingKey) {
  // Setup
  ExpectBootLockboxServiceToBeAvailable(true);
  auto bootlockbox_response = CreateResponseWithBootLockboxError(
      cryptohome::BOOTLOCKBOX_ERROR_MISSING_KEY);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_response.get());

  // Action
  ArcSideloadStatusInterface::Status status;
  arc_sideload_status_->Initialize();
  arc_sideload_status_->QueryAdbSideload(CaptureQueryCallback(&status));

  // Verify
  EXPECT_EQ(status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_FALSE(arc_sideload_status_->IsAdbSideloadAllowed());
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_Uninitialized) {
  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_NE(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_NullResponse) {
  PretendInitialized();

  // Setup
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_, nullptr);

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_NE(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_BadFormat) {
  PretendInitialized();

  // Setup
  auto bootlockbox_response = dbus::Response::CreateEmpty();
  dbus::MessageWriter writer(bootlockbox_response.get());
  writer.AppendString("garbage");
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_,
                                 bootlockbox_response.get());

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_NE(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_RequirePowerwash) {
  PretendInitialized();

  // Setup
  auto bootlockbox_response = CreateResponseWithBootLockboxError(
      cryptohome::BootLockboxErrorCode::BOOTLOCKBOX_ERROR_NVSPACE_UNDEFINED);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_,
                                 bootlockbox_response.get());

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status,
            ArcSideloadStatusInterface::Status::NEED_POWERWASH);
  EXPECT_EQ(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_BootLockboxError) {
  PretendInitialized();

  // Setup
  auto bootlockbox_response = CreateResponseWithBootLockboxError(
      cryptohome::BootLockboxErrorCode::BOOTLOCKBOX_ERROR_NVSPACE_OTHER);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_,
                                 bootlockbox_response.get());

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_EQ(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_AlreadyLogin) {
  PretendInitialized();

  // Setup
  // When bootlockbox is finalized (after any user login), store operation will
  // fail with BOOTLOCKBOX_ERROR_WRITE_LOCKED.
  auto bootlockbox_response = CreateResponseWithBootLockboxError(
      cryptohome::BootLockboxErrorCode::BOOTLOCKBOX_ERROR_WRITE_LOCKED);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_,
                                 bootlockbox_response.get());

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::DISABLED);
  EXPECT_EQ(error, nullptr);
}

TEST_F(ArcSideloadStatusTest, EnableAdbSideload_Success) {
  PretendInitialized();

  // Setup: 1st call to enable
  auto bootlockbox_enable_response = dbus::Response::CreateEmpty();
  dbus::MessageWriter writer(bootlockbox_enable_response.get());
  cryptohome::BootLockboxBaseReply base_reply;
  ASSERT_TRUE(writer.AppendProtoAsArrayOfBytes(base_reply));

  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_store_method_call_,
                                 bootlockbox_enable_response.get());

  // Setup: 2nd call to query
  // NB: This needs to happen to ensure querying from the source of truth.
  auto bootlockbox_query_response = CreateValidQueryResponse(true);
  EXPECT_DBUS_CALL_THEN_CALLBACK(&bootlockbox_read_method_call_,
                                 bootlockbox_query_response.get());

  // Action
  auto sideload_status = ArcSideloadStatusInterface::Status::UNDEFINED;
  char* error;
  arc_sideload_status_->EnableAdbSideload(
      CaptureEnableCallback(&sideload_status, &error));

  // Verify
  EXPECT_EQ(sideload_status, ArcSideloadStatusInterface::Status::ENABLED);
  EXPECT_EQ(error, nullptr);
}

#undef EXPECT_DBUS_CALL_THEN_CALLBACK

}  // namespace login_manager
