// 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 "chromeos/components/multidevice/remote_device_ref.h"
#include "chromeos/components/multidevice/remote_device_test_util.h"
#include "components/cryptauth/mock_cryptauth_client.h"
#include "components/cryptauth/proto/enum_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

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

namespace cryptauth {

namespace {

enum class Result { kSuccess, kErrorSettingFeature, kErrorFindingEligible };

// Arbitrarily choose different error types which match to Result types.
const NetworkRequestError kErrorSettingFeatureNetworkRequestError =
    NetworkRequestError::kOffline;
const NetworkRequestError kErrorFindingEligibleNetworkRequestError =
    NetworkRequestError::kEndpointNotFound;

const char kBetterTogetherHostCallbackBluetoothAddress[] =
    "BETTER_TOGETHER_HOST";
const char kBetterTogetherClientCallbackBluetoothAddress[] =
    "BETTER_TOGETHER_CLIENT";

std::vector<cryptauth::ExternalDeviceInfo>
CreateExternalDeviceInfosForRemoteDevices(
    const chromeos::multidevice::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
    // chromeos::multidevice::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(
                chromeos::multidevice::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_ = kErrorSettingFeatureNetworkRequestError;
  }

  // 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_ = kErrorFindingEligibleNetworkRequestError;
  }

  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_ = Result::kSuccess; }

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

  void OnError(NetworkRequestError error) {
    if (error == kErrorSettingFeatureNetworkRequestError)
      result_ = Result::kErrorSettingFeature;
    else if (error == kErrorFindingEligibleNetworkRequestError)
      result_ = Result::kErrorFindingEligible;
    else
      NOTREACHED();
  }

  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_);
  }

  Result GetResultAndReset() {
    EXPECT_TRUE(result_);
    Result result = *result_;
    result_.reset();
    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.
  base::Optional<Result> result_;

  // The code passed to the error callback; varies depending on what
  // CryptAuthClient function is invoked.
  base::Optional<NetworkRequestError> 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(SoftwareFeatureEnumToString(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(Result::kSuccess, GetResultAndReset());

  EXPECT_EQ(SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST),
            last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherHostCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(Result::kSuccess, GetResultAndReset());
  VerifyDeviceEligibility();

  EXPECT_EQ(
      SoftwareFeatureEnumToString(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(Result::kSuccess, GetResultAndReset());

  EXPECT_EQ(
      SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_CLIENT),
      last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherClientCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(Result::kSuccess, 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(SoftwareFeatureEnumToString(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(Result::kErrorSettingFeature, GetResultAndReset());

  EXPECT_EQ(
      SoftwareFeatureEnumToString(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(Result::kSuccess, GetResultAndReset());

  EXPECT_EQ(SoftwareFeatureEnumToString(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(Result::kSuccess, GetResultAndReset());
}

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

  EXPECT_EQ(SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST),
            last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherHostCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(Result::kSuccess, GetResultAndReset());
  VerifyDeviceEligibility();

  EXPECT_EQ(
      SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_CLIENT),
      last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherClientCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeErrorCallback();
  EXPECT_EQ(Result::kErrorFindingEligible, GetResultAndReset());

  EXPECT_EQ(SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST),
            last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherHostCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeFindEligibleDevicesCallback(CreateFindEligibleUnlockDevicesResponse());
  EXPECT_EQ(Result::kSuccess, 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(SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST),
            last_toggle_request_.feature());
  InvokeErrorCallback();
  EXPECT_EQ(Result::kErrorSettingFeature, GetResultAndReset());

  EXPECT_EQ(SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST),
            last_find_request_.feature());
  EXPECT_EQ(kBetterTogetherHostCallbackBluetoothAddress,
            last_find_request_.callback_bluetooth_address());
  InvokeErrorCallback();
  EXPECT_EQ(Result::kErrorFindingEligible, GetResultAndReset());
}

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

  EXPECT_EQ(SoftwareFeatureEnumToString(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(Result::kErrorSettingFeature, GetResultAndReset());
}

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

  EXPECT_EQ(SoftwareFeatureEnumToString(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(Result::kErrorSettingFeature, GetResultAndReset());
}

}  // namespace cryptauth
