// Copyright 2017 The Chromium 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 "components/cryptauth/software_feature_manager_impl.h"

#include "base/bind.h"
#include "base/macros.h"
#include "components/cryptauth/mock_cryptauth_client.h"
#include "components/cryptauth/remote_device_ref.h"
#include "components/cryptauth/remote_device_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Invoke;

namespace cryptauth {

namespace {

const char kSuccessResult[] = "success";
const char kErrorSetSoftwareFeatureState[] = "setSoftwareFeatureStateError";
const char kErrorFindEligibleDevices[] = "findEligibleDevicesError";

std::vector<cryptauth::ExternalDeviceInfo>
CreateExternalDeviceInfosForRemoteDevices(
    const cryptauth::RemoteDeviceRefList remote_devices) {
  std::vector<cryptauth::ExternalDeviceInfo> device_infos;
  for (const auto& remote_device : remote_devices) {
    // Add an ExternalDeviceInfo with the same public key as the RemoteDevice.
    cryptauth::ExternalDeviceInfo info;
    info.set_public_key(remote_device.public_key());
    device_infos.push_back(info);
  }
  return device_infos;
}

}  // namespace

class CryptAuthSoftwareFeatureManagerImplTest
    : public testing::Test,
      public MockCryptAuthClientFactory::Observer {
 public:
  CryptAuthSoftwareFeatureManagerImplTest()
      : all_test_external_device_infos_(
            CreateExternalDeviceInfosForRemoteDevices(
                cryptauth::CreateRemoteDeviceRefListForTest(5))),
        test_eligible_external_devices_infos_(
            {all_test_external_device_infos_[0],
             all_test_external_device_infos_[1],
             all_test_external_device_infos_[2]}),
        test_ineligible_external_devices_infos_(
            {all_test_external_device_infos_[3],
             all_test_external_device_infos_[4]}) {}

  void SetUp() override {
    mock_cryptauth_client_factory_ =
        std::make_unique<MockCryptAuthClientFactory>(
            MockCryptAuthClientFactory::MockType::MAKE_NICE_MOCKS);
    mock_cryptauth_client_factory_->AddObserver(this);
    software_feature_manager_ =
        SoftwareFeatureManagerImpl::Factory::NewInstance(
            mock_cryptauth_client_factory_.get());
  }

  void TearDown() override {
    mock_cryptauth_client_factory_->RemoveObserver(this);
  }

  void OnCryptAuthClientCreated(MockCryptAuthClient* client) override {
    ON_CALL(*client, ToggleEasyUnlock(_, _, _))
        .WillByDefault(Invoke(
            this,
            &CryptAuthSoftwareFeatureManagerImplTest::MockToggleEasyUnlock));
    ON_CALL(*client, FindEligibleUnlockDevices(_, _, _))
        .WillByDefault(Invoke(this, &CryptAuthSoftwareFeatureManagerImplTest::
                                        MockFindEligibleUnlockDevices));
  }

  // Mock CryptAuthClient::ToggleEasyUnlock() implementation.
  void MockToggleEasyUnlock(
      const ToggleEasyUnlockRequest& request,
      const CryptAuthClient::ToggleEasyUnlockCallback& callback,
      const CryptAuthClient::ErrorCallback& error_callback) {
    last_toggle_request_ = request;
    toggle_easy_unlock_callback_ = callback;
    error_callback_ = error_callback;
    error_code_ = kErrorSetSoftwareFeatureState;
  }

  // Mock CryptAuthClient::FindEligibleUnlockDevices() implementation.
  void MockFindEligibleUnlockDevices(
      const FindEligibleUnlockDevicesRequest& request,
      const CryptAuthClient::FindEligibleUnlockDevicesCallback& callback,
      const CryptAuthClient::ErrorCallback& error_callback) {
    last_find_request_ = request;
    find_eligible_unlock_devices_callback_ = callback;
    error_callback_ = error_callback;
    error_code_ = kErrorFindEligibleDevices;
  }

  FindEligibleUnlockDevicesResponse CreateFindEligibleUnlockDevicesResponse() {
    FindEligibleUnlockDevicesResponse find_eligible_unlock_devices_response;
    for (const auto& device_info : test_eligible_external_devices_infos_) {
      find_eligible_unlock_devices_response.add_eligible_devices()->CopyFrom(
          device_info);
    }
    for (const auto& device_info : test_ineligible_external_devices_infos_) {
      find_eligible_unlock_devices_response.add_ineligible_devices()
          ->mutable_device()
          ->CopyFrom(device_info);
    }
    return find_eligible_unlock_devices_response;
  }

  void VerifyDeviceEligibility() {
    // Ensure that resulting devices are not empty.  Otherwise, following for
    // loop checks will succeed on empty resulting devices.
    EXPECT_TRUE(result_eligible_devices_.size() > 0);
    EXPECT_TRUE(result_ineligible_devices_.size() > 0);
    for (const auto& device_info : result_eligible_devices_) {
      EXPECT_TRUE(
          std::find_if(
              test_eligible_external_devices_infos_.begin(),
              test_eligible_external_devices_infos_.end(),
              [&device_info](const cryptauth::ExternalDeviceInfo& device) {
                return device.public_key() == device_info.public_key();
              }) != test_eligible_external_devices_infos_.end());
    }
    for (const auto& ineligible_device : result_ineligible_devices_) {
      EXPECT_TRUE(
          std::find_if(test_ineligible_external_devices_infos_.begin(),
                       test_ineligible_external_devices_infos_.end(),
                       [&ineligible_device](
                           const cryptauth::ExternalDeviceInfo& device) {
                         return device.public_key() ==
                                ineligible_device.device().public_key();
                       }) != test_ineligible_external_devices_infos_.end());
    }
    result_eligible_devices_.clear();
    result_ineligible_devices_.clear();
  }

  void SetSoftwareFeatureState(SoftwareFeature feature,
                               const ExternalDeviceInfo& device_info,
                               bool enabled,
                               bool is_exclusive = false) {
    software_feature_manager_->SetSoftwareFeatureState(
        device_info.public_key(), feature, enabled,
        base::Bind(
            &CryptAuthSoftwareFeatureManagerImplTest::OnSoftwareFeatureStateSet,
            base::Unretained(this)),
        base::Bind(&CryptAuthSoftwareFeatureManagerImplTest::OnError,
                   base::Unretained(this)),
        is_exclusive);
  }

  void FindEligibleDevices(SoftwareFeature feature) {
    software_feature_manager_->FindEligibleDevices(
        feature,
        base::Bind(
            &CryptAuthSoftwareFeatureManagerImplTest::OnEligibleDevicesFound,
            base::Unretained(this)),
        base::Bind(&CryptAuthSoftwareFeatureManagerImplTest::OnError,
                   base::Unretained(this)));
  }

  void OnSoftwareFeatureStateSet() { result_ = kSuccessResult; }

  void OnEligibleDevicesFound(
      const std::vector<ExternalDeviceInfo>& eligible_devices,
      const std::vector<IneligibleDevice>& ineligible_devices) {
    result_ = kSuccessResult;
    result_eligible_devices_ = eligible_devices;
    result_ineligible_devices_ = ineligible_devices;
  }

  void OnError(const std::string& error_message) { result_ = error_message; }

  void InvokeSetSoftwareFeatureCallback() {
    CryptAuthClient::ToggleEasyUnlockCallback success_callback =
        toggle_easy_unlock_callback_;
    ASSERT_TRUE(!success_callback.is_null());
    toggle_easy_unlock_callback_.Reset();
    success_callback.Run(ToggleEasyUnlockResponse());
  }

  void InvokeFindEligibleDevicesCallback(
      const FindEligibleUnlockDevicesResponse& retrieved_devices_response) {
    CryptAuthClient::FindEligibleUnlockDevicesCallback success_callback =
        find_eligible_unlock_devices_callback_;
    ASSERT_TRUE(!success_callback.is_null());
    find_eligible_unlock_devices_callback_.Reset();
    success_callback.Run(retrieved_devices_response);
  }

  void InvokeErrorCallback() {
    CryptAuthClient::ErrorCallback error_callback = error_callback_;
    ASSERT_TRUE(!error_callback.is_null());
    error_callback_.Reset();
    error_callback.Run(error_code_);
  }

  std::string GetResultAndReset() {
    std::string result;
    result.swap(result_);
    return result;
  }

  const std::vector<cryptauth::ExternalDeviceInfo>
      all_test_external_device_infos_;
  const std::vector<ExternalDeviceInfo> test_eligible_external_devices_infos_;
  const std::vector<ExternalDeviceInfo> test_ineligible_external_devices_infos_;

  std::unique_ptr<MockCryptAuthClientFactory> mock_cryptauth_client_factory_;
  std::unique_ptr<cryptauth::SoftwareFeatureManager> software_feature_manager_;

  CryptAuthClient::ErrorCallback error_callback_;

  // Set when a CryptAuthClient function returns. If empty, no callback has been
  // invoked.
  std::string result_;

  // The code passed to the error callback; varies depending on what
  // CryptAuthClient function is invoked.
  std::string error_code_;

  // For SetSoftwareFeatureState() tests.
  ToggleEasyUnlockRequest last_toggle_request_;
  CryptAuthClient::ToggleEasyUnlockCallback toggle_easy_unlock_callback_;

  // For FindEligibleDevices() tests.
  FindEligibleUnlockDevicesRequest last_find_request_;
  CryptAuthClient::FindEligibleUnlockDevicesCallback
      find_eligible_unlock_devices_callback_;
  std::vector<ExternalDeviceInfo> result_eligible_devices_;
  std::vector<IneligibleDevice> result_ineligible_devices_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CryptAuthSoftwareFeatureManagerImplTest);
};

TEST_F(CryptAuthSoftwareFeatureManagerImplTest, TestOrderUponMultipleRequests) {
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_HOST,
                          test_eligible_external_devices_infos_[0],
                          true /* enable */);
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_HOST);
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_CLIENT,
                          test_eligible_external_devices_infos_[1],
                          false /* enable */);
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_CLIENT);

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_toggle_request_.feature());
  EXPECT_EQ(true, last_toggle_request_.enable());
  EXPECT_EQ(false, last_toggle_request_.is_exclusive());
  InvokeSetSoftwareFeatureCallback();
  EXPECT_EQ(kSuccessResult, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_find_request_.feature());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(kSuccessResult, GetResultAndReset());
  VerifyDeviceEligibility();

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_CLIENT,
            last_toggle_request_.feature());
  EXPECT_EQ(false, last_toggle_request_.enable());
  EXPECT_EQ(false, last_toggle_request_.is_exclusive());
  InvokeSetSoftwareFeatureCallback();
  EXPECT_EQ(kSuccessResult, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_CLIENT,
            last_find_request_.feature());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(kSuccessResult, GetResultAndReset());
  VerifyDeviceEligibility();
}

TEST_F(CryptAuthSoftwareFeatureManagerImplTest,
       TestMultipleSetUnlocksRequests) {
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_HOST,
                          test_eligible_external_devices_infos_[0],
                          true /* enable */);
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_CLIENT,
                          test_eligible_external_devices_infos_[1],
                          false /* enable */);
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_HOST,
                          test_eligible_external_devices_infos_[2],
                          true /* enable */);

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_toggle_request_.feature());
  EXPECT_EQ(true, last_toggle_request_.enable());
  EXPECT_EQ(false, last_toggle_request_.is_exclusive());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorSetSoftwareFeatureState, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_CLIENT,
            last_toggle_request_.feature());
  EXPECT_EQ(false, last_toggle_request_.enable());
  EXPECT_EQ(false, last_toggle_request_.is_exclusive());
  InvokeSetSoftwareFeatureCallback();
  EXPECT_EQ(kSuccessResult, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_toggle_request_.feature());
  EXPECT_EQ(true, last_toggle_request_.enable());
  EXPECT_EQ(false, last_toggle_request_.is_exclusive());
  InvokeSetSoftwareFeatureCallback();
  EXPECT_EQ(kSuccessResult, GetResultAndReset());
}

TEST_F(CryptAuthSoftwareFeatureManagerImplTest,
       TestMultipleFindEligibleForUnlockDevicesRequests) {
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_HOST);
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_CLIENT);
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_HOST);

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_find_request_.feature());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(kSuccessResult, GetResultAndReset());
  VerifyDeviceEligibility();

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_CLIENT,
            last_find_request_.feature());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorFindEligibleDevices, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_find_request_.feature());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(kSuccessResult, GetResultAndReset());
  VerifyDeviceEligibility();
}

TEST_F(CryptAuthSoftwareFeatureManagerImplTest, TestOrderViaMultipleErrors) {
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_HOST,
                          test_eligible_external_devices_infos_[0],
                          true /* enable */);
  FindEligibleDevices(SoftwareFeature::BETTER_TOGETHER_HOST);

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_toggle_request_.feature());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorSetSoftwareFeatureState, GetResultAndReset());

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_find_request_.feature());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorFindEligibleDevices, GetResultAndReset());
}

TEST_F(CryptAuthSoftwareFeatureManagerImplTest, TestIsExclusive) {
  SetSoftwareFeatureState(SoftwareFeature::BETTER_TOGETHER_HOST,
                          test_eligible_external_devices_infos_[0],
                          true /* enable */, true /* is_exclusive */);

  EXPECT_EQ(SoftwareFeature::BETTER_TOGETHER_HOST,
            last_toggle_request_.feature());
  EXPECT_EQ(true, last_toggle_request_.enable());
  EXPECT_EQ(true, last_toggle_request_.is_exclusive());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorSetSoftwareFeatureState, GetResultAndReset());
}

TEST_F(CryptAuthSoftwareFeatureManagerImplTest, TestEasyUnlockSpecialCase) {
  SetSoftwareFeatureState(SoftwareFeature::EASY_UNLOCK_HOST,
                          test_eligible_external_devices_infos_[0],
                          false /* enable */);

  EXPECT_EQ(SoftwareFeature::EASY_UNLOCK_HOST, last_toggle_request_.feature());
  EXPECT_EQ(false, last_toggle_request_.enable());
  // apply_to_all() should be false when disabling EasyUnlock host capabilities.
  EXPECT_EQ(true, last_toggle_request_.apply_to_all());
  EXPECT_FALSE(last_toggle_request_.has_public_key());
  InvokeErrorCallback();
  EXPECT_EQ(kErrorSetSoftwareFeatureState, GetResultAndReset());
}

}  // namespace cryptauth
