// 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 "chrome/browser/ash/tether/tether_service.h"

#include <memory>

#include "ash/components/multidevice/remote_device_test_util.h"
#include "ash/components/multidevice/software_feature.h"
#include "ash/components/tether/fake_notification_presenter.h"
#include "ash/components/tether/fake_tether_component.h"
#include "ash/components/tether/fake_tether_host_fetcher.h"
#include "ash/components/tether/tether_component_impl.h"
#include "ash/components/tether/tether_host_fetcher_impl.h"
#include "ash/constants/ash_features.h"
#include "ash/services/device_sync/cryptauth_device_manager.h"
#include "ash/services/device_sync/cryptauth_enroller.h"
#include "ash/services/device_sync/cryptauth_enrollment_manager.h"
#include "ash/services/device_sync/fake_cryptauth_enrollment_manager.h"
#include "ash/services/device_sync/fake_remote_device_provider.h"
#include "ash/services/device_sync/public/cpp/device_sync_client_impl.h"
#include "ash/services/device_sync/public/cpp/fake_device_sync_client.h"
#include "ash/services/device_sync/remote_device_provider_impl.h"
#include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
#include "ash/services/multidevice_setup/public/cpp/multidevice_setup_client_impl.h"
#include "ash/services/multidevice_setup/public/cpp/prefs.h"
#include "ash/services/secure_channel/public/cpp/client/fake_secure_channel_client.h"
#include "ash/services/secure_channel/public/cpp/client/secure_channel_client_impl.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/timer/mock_timer.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/ui/ash/network/tether_notification_presenter.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/ash/components/network/network_connect.h"
#include "chromeos/ash/components/network/network_handler.h"
#include "chromeos/ash/components/network/network_handler_test_helper.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_type_pattern.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "chromeos/dbus/shill/shill_device_client.h"
#include "chromeos/dbus/shill/shill_manager_client.h"
#include "chromeos/dbus/shill/shill_service_client.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"

namespace ash {
namespace tether {

namespace {

using ::testing::Invoke;
using ::testing::NiceMock;

const char kTestUserPrivateKey[] = "kTestUserPrivateKey";
const size_t kNumTestDevices = 5;

multidevice::RemoteDeviceRefList CreateTestDevices() {
  multidevice::RemoteDeviceRefList list;
  for (size_t i = 0; i < kNumTestDevices; ++i) {
    list.push_back(multidevice::RemoteDeviceRefBuilder()
                       .SetSupportsMobileHotspot(true)
                       .SetSoftwareFeatureState(
                           multidevice::SoftwareFeature::kBetterTogetherHost,
                           multidevice::SoftwareFeatureState::kSupported)
                       .Build());
  }
  return list;
}

class TestTetherService : public TetherService {
 public:
  TestTetherService(
      Profile* profile,
      chromeos::PowerManagerClient* power_manager_client,
      device_sync::DeviceSyncClient* device_sync_client,
      secure_channel::SecureChannelClient* secure_channel_client,
      multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
      chromeos::NetworkStateHandler* network_state_handler,
      session_manager::SessionManager* session_manager)
      : TetherService(profile,
                      power_manager_client,
                      device_sync_client,
                      secure_channel_client,
                      multidevice_setup_client,
                      network_state_handler,
                      session_manager) {}
  ~TestTetherService() override {}

  int updated_technology_state_count() {
    return updated_technology_state_count_;
  }

 protected:
  void UpdateTetherTechnologyState() override {
    updated_technology_state_count_++;
    TetherService::UpdateTetherTechnologyState();
  }

 private:
  int updated_technology_state_count_ = 0;
};

class FakeTetherComponentWithDestructorCallback : public FakeTetherComponent {
 public:
  FakeTetherComponentWithDestructorCallback(
      base::OnceClosure destructor_callback)
      : FakeTetherComponent(/*has_asynchronous_shutdown=*/false),
        destructor_callback_(std::move(destructor_callback)) {}

  ~FakeTetherComponentWithDestructorCallback() override {
    std::move(destructor_callback_).Run();
  }

 private:
  base::OnceClosure destructor_callback_;
};

class TestTetherComponentFactory final : public TetherComponentImpl::Factory {
 public:
  TestTetherComponentFactory() {}

  // Returns nullptr if no TetherComponent has been created or if the last one
  // that was created has already been deleted.
  FakeTetherComponentWithDestructorCallback* active_tether_component() {
    return active_tether_component_;
  }

  // TetherComponentImpl::Factory:
  std::unique_ptr<TetherComponent> CreateInstance(
      device_sync::DeviceSyncClient* device_sync_client,
      secure_channel::SecureChannelClient* secure_channel_client,
      TetherHostFetcher* tether_host_fetcher,
      NotificationPresenter* notification_presenter,
      GmsCoreNotificationsStateTrackerImpl*
          gms_core_notifications_state_tracker,
      PrefService* pref_service,
      chromeos::NetworkStateHandler* network_state_handler,
      ManagedNetworkConfigurationHandler* managed_network_configuration_handler,
      NetworkConnect* network_connect,
      NetworkConnectionHandler* network_connection_handler,
      scoped_refptr<device::BluetoothAdapter> adapter,
      session_manager::SessionManager* session_manager) override {
    active_tether_component_ =
        new FakeTetherComponentWithDestructorCallback(base::BindOnce(
            &TestTetherComponentFactory::OnActiveTetherComponentDeleted,
            base::Unretained(this)));
    was_tether_component_active_ = true;
    return base::WrapUnique(active_tether_component_);
  }

  bool was_tether_component_active() { return was_tether_component_active_; }

  const TetherComponent::ShutdownReason& last_shutdown_reason() {
    return last_shutdown_reason_;
  }

 private:
  void OnActiveTetherComponentDeleted() {
    last_shutdown_reason_ = *active_tether_component_->last_shutdown_reason();
    active_tether_component_ = nullptr;
  }

  FakeTetherComponentWithDestructorCallback* active_tether_component_ = nullptr;
  bool was_tether_component_active_ = false;
  TetherComponent::ShutdownReason last_shutdown_reason_;
};

class FakeRemoteDeviceProviderFactory
    : public device_sync::RemoteDeviceProviderImpl::Factory {
 public:
  FakeRemoteDeviceProviderFactory() = default;
  ~FakeRemoteDeviceProviderFactory() override = default;

  // device_sync::RemoteDeviceProviderImpl::Factory:
  std::unique_ptr<device_sync::RemoteDeviceProvider> CreateInstance(
      device_sync::CryptAuthDeviceManager* device_manager,
      device_sync::CryptAuthV2DeviceManager* v2_device_manager,
      const std::string& user_email,
      const std::string& user_private_key) override {
    return std::make_unique<device_sync::FakeRemoteDeviceProvider>();
  }
};

class FakeTetherHostFetcherFactory : public TetherHostFetcherImpl::Factory {
 public:
  FakeTetherHostFetcherFactory(
      const multidevice::RemoteDeviceRefList& initial_devices)
      : initial_devices_(initial_devices) {}
  virtual ~FakeTetherHostFetcherFactory() = default;

  FakeTetherHostFetcher* last_created() { return last_created_; }

  void SetNoInitialDevices() { initial_devices_.clear(); }

  // TetherHostFetcherImpl::Factory :
  std::unique_ptr<TetherHostFetcher> CreateInstance(
      device_sync::DeviceSyncClient* device_sync_client,
      multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client)
      override {
    last_created_ = new FakeTetherHostFetcher(initial_devices_);
    return base::WrapUnique(last_created_);
  }

 private:
  multidevice::RemoteDeviceRefList initial_devices_;
  FakeTetherHostFetcher* last_created_ = nullptr;
};

class FakeDeviceSyncClientImplFactory
    : public device_sync::DeviceSyncClientImpl::Factory {
 public:
  FakeDeviceSyncClientImplFactory() = default;

  ~FakeDeviceSyncClientImplFactory() override = default;

  // device_sync::DeviceSyncClientImpl::Factory:
  std::unique_ptr<device_sync::DeviceSyncClient> CreateInstance() override {
    auto fake_device_sync_client =
        std::make_unique<device_sync::FakeDeviceSyncClient>();
    fake_device_sync_client->NotifyReady();
    return fake_device_sync_client;
  }
};

class FakeSecureChannelClientImplFactory
    : public secure_channel::SecureChannelClientImpl::Factory {
 public:
  FakeSecureChannelClientImplFactory() = default;

  ~FakeSecureChannelClientImplFactory() override = default;

  // secure_channel::SecureChannelClientImpl::Factory:
  std::unique_ptr<secure_channel::SecureChannelClient> CreateInstance(
      mojo::PendingRemote<secure_channel::mojom::SecureChannel> channel,
      scoped_refptr<base::TaskRunner> task_runner) override {
    return std::make_unique<secure_channel::FakeSecureChannelClient>();
  }
};

class FakeMultiDeviceSetupClientImplFactory
    : public multidevice_setup::MultiDeviceSetupClientImpl::Factory {
 public:
  FakeMultiDeviceSetupClientImplFactory() = default;

  ~FakeMultiDeviceSetupClientImplFactory() override = default;

  // multidevice_setup::MultiDeviceSetupClientImpl::Factory:
  std::unique_ptr<multidevice_setup::MultiDeviceSetupClient> CreateInstance(
      mojo::PendingRemote<multidevice_setup::mojom::MultiDeviceSetup>)
      override {
    auto fake_multidevice_setup_client =
        std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
    fake_multidevice_setup_client_ = fake_multidevice_setup_client.get();
    return fake_multidevice_setup_client;
  }

  multidevice_setup::FakeMultiDeviceSetupClient*
  fake_multidevice_setup_client() {
    return fake_multidevice_setup_client_;
  }

 private:
  multidevice_setup::FakeMultiDeviceSetupClient* fake_multidevice_setup_client_;
};

}  // namespace

class TetherServiceTest : public testing::Test {
 public:
  TetherServiceTest(const TetherServiceTest&) = delete;
  TetherServiceTest& operator=(const TetherServiceTest&) = delete;

 protected:
  TetherServiceTest() : test_devices_(CreateTestDevices()) {}
  ~TetherServiceTest() override {}

  void SetUp() override {
    fake_notification_presenter_ = nullptr;
    mock_timer_ = nullptr;

    NetworkConnect::Initialize(nullptr);

    TestingProfile::Builder builder;
    profile_ = builder.Build();

    fake_chrome_user_manager_ = new FakeChromeUserManager();
    scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
        base::WrapUnique(fake_chrome_user_manager_));

    chromeos::PowerManagerClient::InitializeFake();

    fake_device_sync_client_ =
        std::make_unique<device_sync::FakeDeviceSyncClient>();
    fake_device_sync_client_->NotifyReady();

    fake_device_sync_client_impl_factory_ =
        std::make_unique<FakeDeviceSyncClientImplFactory>();
    device_sync::DeviceSyncClientImpl::Factory::SetFactoryForTesting(
        fake_device_sync_client_impl_factory_.get());

    fake_secure_channel_client_ =
        std::make_unique<secure_channel::FakeSecureChannelClient>();
    fake_secure_channel_client_impl_factory_ =
        std::make_unique<FakeSecureChannelClientImplFactory>();
    secure_channel::SecureChannelClientImpl::Factory::SetFactoryForTesting(
        fake_secure_channel_client_impl_factory_.get());

    fake_multidevice_setup_client_ =
        std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
    fake_multidevice_setup_client_impl_factory_ =
        std::make_unique<FakeMultiDeviceSetupClientImplFactory>();
    multidevice_setup::MultiDeviceSetupClientImpl::Factory::
        SetFactoryForTesting(fake_multidevice_setup_client_impl_factory_.get());
    initial_feature_state_ =
        multidevice_setup::mojom::FeatureState::kEnabledByUser;

    fake_enrollment_manager_ =
        std::make_unique<device_sync::FakeCryptAuthEnrollmentManager>();
    fake_enrollment_manager_->set_user_private_key(kTestUserPrivateKey);

    mock_adapter_ =
        base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>();
    SetIsBluetoothPowered(true);
    is_adapter_present_ = true;
    ON_CALL(*mock_adapter_, IsPresent())
        .WillByDefault(Invoke(this, &TetherServiceTest::IsBluetoothPresent));
    ON_CALL(*mock_adapter_, IsPowered())
        .WillByDefault(Invoke(this, &TetherServiceTest::IsBluetoothPowered));
    device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);

    test_tether_component_factory_ =
        base::WrapUnique(new TestTetherComponentFactory());
    TetherComponentImpl::Factory::SetFactoryForTesting(
        test_tether_component_factory_.get());
    shutdown_reason_verified_ = false;

    fake_remote_device_provider_factory_ =
        base::WrapUnique(new FakeRemoteDeviceProviderFactory());
    device_sync::RemoteDeviceProviderImpl::Factory::SetFactoryForTesting(
        fake_remote_device_provider_factory_.get());

    fake_tether_host_fetcher_factory_ =
        base::WrapUnique(new FakeTetherHostFetcherFactory(test_devices_));
    TetherHostFetcherImpl::Factory::SetFactoryForTesting(
        fake_tether_host_fetcher_factory_.get());

    TestingBrowserProcess::GetGlobal()->SetLocalState(&local_pref_service_);
    RegisterLocalState(local_pref_service_.registry());
  }

  void TearDown() override {
    TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr);

    device_sync::DeviceSyncClientImpl::Factory::SetFactoryForTesting(nullptr);
    secure_channel::SecureChannelClientImpl::Factory::SetFactoryForTesting(
        nullptr);
    multidevice_setup::MultiDeviceSetupClientImpl::Factory::
        SetFactoryForTesting(nullptr);

    ShutdownTetherService();

    if (tether_service_) {
      // As of crbug.com/798605, SHUT_DOWN should not be logged since it does
      // not contribute meaningful data.
      histogram_tester_.ExpectBucketCount(
          "InstantTethering.FeatureState",
          TetherService::TetherFeatureState::SHUT_DOWN, 0 /* count */);
      tether_service_.reset();
    }

    EXPECT_EQ(test_tether_component_factory_->was_tether_component_active(),
              shutdown_reason_verified_);

    chromeos::PowerManagerClient::Shutdown();
    NetworkConnect::Shutdown();
  }

  void SetPrimaryUserLoggedIn() {
    const AccountId account_id(
        AccountId::FromUserEmail(profile_->GetProfileUserName()));
    const user_manager::User* user =
        fake_chrome_user_manager_->AddPublicAccountUser(account_id);
    fake_chrome_user_manager_->UserLoggedIn(account_id, user->username_hash(),
                                            false /* browser_restart */,
                                            false /* is_child */);
  }

  void CreateTetherService() {
    fake_multidevice_setup_client_->SetFeatureState(
        multidevice_setup::mojom::Feature::kInstantTethering,
        initial_feature_state_);

    tether_service_ = base::WrapUnique(new TestTetherService(
        profile_.get(), chromeos::FakePowerManagerClient::Get(),
        fake_device_sync_client_.get(), fake_secure_channel_client_.get(),
        fake_multidevice_setup_client_.get(), network_state_handler(),
        nullptr /* session_manager */));

    fake_notification_presenter_ = new FakeNotificationPresenter();
    mock_timer_ = new base::MockOneShotTimer();
    tether_service_->SetTestDoubles(
        base::WrapUnique(fake_notification_presenter_),
        base::WrapUnique(mock_timer_));

    SetPrimaryUserLoggedIn();

    // Ensure that TetherService does not prematurely update its
    // TechnologyState before it fetches the BluetoothAdapter.
    EXPECT_EQ(
        chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
        network_state_handler()->GetTechnologyState(
            NetworkTypePattern::Tether()));
    VerifyTetherActiveStatus(false /* expected_active */);

    if (!fake_device_sync_client_->is_ready()) {
      return;
    }

    // Allow the posted task to fetch the BluetoothAdapter to finish.
    base::RunLoop().RunUntilIdle();
  }

  void ShutdownTetherService() {
    if (tether_service_)
      tether_service_->Shutdown();
  }

  void SetTetherTechnologyStateEnabled(bool enabled) {
    network_state_handler()->SetTetherTechnologyState(
        enabled
            ? chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED
            : chromeos::NetworkStateHandler::TechnologyState::
                  TECHNOLOGY_AVAILABLE);
  }

  void SetCellularTechnologyStateEnabled(bool enabled) {
    network_state_handler()->SetTechnologyEnabled(
        NetworkTypePattern::Cellular(), enabled,
        network_handler::ErrorCallback());
    base::RunLoop().RunUntilIdle();
  }

  void SetIsBluetoothPowered(bool powered) {
    is_adapter_powered_ = powered;
    for (auto& observer : mock_adapter_->GetObservers())
      observer.AdapterPoweredChanged(mock_adapter_.get(), powered);
  }

  void set_is_adapter_present(bool present) { is_adapter_present_ = present; }

  bool IsBluetoothPresent() { return is_adapter_present_; }
  bool IsBluetoothPowered() { return is_adapter_powered_; }

  void RemoveWifiFromSystem() {
    manager_test()->RemoveTechnology(shill::kTypeWifi);
    base::RunLoop().RunUntilIdle();
  }

  void DisconnectDefaultShillNetworks() {
    const NetworkState* default_state;
    while ((default_state = network_state_handler()->DefaultNetwork())) {
      network_handler_test_helper_.service_test()->SetServiceProperty(
          default_state->path(), shill::kStateProperty,
          base::Value(shill::kStateIdle));
      base::RunLoop().RunUntilIdle();
    }
  }

  void VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState expected_technology_state_and_reason,
      int expected_count) {
    histogram_tester_.ExpectBucketCount("InstantTethering.FeatureState",
                                        expected_technology_state_and_reason,
                                        expected_count);
  }

  void VerifyTetherActiveStatus(bool expected_active) {
    EXPECT_EQ(
        expected_active,
        test_tether_component_factory_->active_tether_component() != nullptr);
  }

  void VerifyLastShutdownReason(
      const TetherComponent::ShutdownReason& expected_shutdown_reason) {
    EXPECT_EQ(expected_shutdown_reason,
              test_tether_component_factory_->last_shutdown_reason());
    shutdown_reason_verified_ = true;
  }

  chromeos::ShillManagerClient::TestInterface* manager_test() {
    return network_handler_test_helper_.manager_test();
  }

  chromeos::NetworkStateHandler* network_state_handler() {
    return chromeos::NetworkHandler::Get()->network_state_handler();
  }

  const multidevice::RemoteDeviceRefList test_devices_;
  const content::BrowserTaskEnvironment task_environment_;

  NetworkHandlerTestHelper network_handler_test_helper_;
  std::unique_ptr<TestingProfile> profile_;
  FakeChromeUserManager* fake_chrome_user_manager_;
  std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
  std::unique_ptr<sync_preferences::TestingPrefServiceSyncable>
      test_pref_service_;
  std::unique_ptr<TestTetherComponentFactory> test_tether_component_factory_;
  std::unique_ptr<FakeRemoteDeviceProviderFactory>
      fake_remote_device_provider_factory_;
  std::unique_ptr<FakeTetherHostFetcherFactory>
      fake_tether_host_fetcher_factory_;
  FakeNotificationPresenter* fake_notification_presenter_;
  base::MockOneShotTimer* mock_timer_;
  std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_;
  std::unique_ptr<FakeDeviceSyncClientImplFactory>
      fake_device_sync_client_impl_factory_;
  std::unique_ptr<secure_channel::FakeSecureChannelClient>
      fake_secure_channel_client_;
  std::unique_ptr<FakeSecureChannelClientImplFactory>
      fake_secure_channel_client_impl_factory_;
  std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient>
      fake_multidevice_setup_client_;
  std::unique_ptr<FakeMultiDeviceSetupClientImplFactory>
      fake_multidevice_setup_client_impl_factory_;
  std::unique_ptr<device_sync::FakeCryptAuthEnrollmentManager>
      fake_enrollment_manager_;

  multidevice_setup::mojom::FeatureState initial_feature_state_;

  scoped_refptr<device::MockBluetoothAdapter> mock_adapter_;
  bool is_adapter_present_;
  bool is_adapter_powered_;
  bool shutdown_reason_verified_;

  // PrefService which contains the browser process' local storage.
  TestingPrefServiceSimple local_pref_service_;

  std::unique_ptr<TestTetherService> tether_service_;

  base::HistogramTester histogram_tester_;
};

TEST_F(TetherServiceTest, TestShutdown) {
  CreateTetherService();
  VerifyTetherActiveStatus(true /* expected_active */);

  ShutdownTetherService();

  // The TechnologyState should not have changed due to Shutdown() being called.
  // If it had changed, any settings UI that was previously open would have
  // shown visual jank.
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestAsyncTetherShutdown) {
  CreateTetherService();

  // Tether should be ENABLED, and there should be no AsyncShutdownTask.
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  // Use an asynchronous shutdown.
  test_tether_component_factory_->active_tether_component()
      ->set_has_asynchronous_shutdown(true);

  // Disable the Tether preference. This should trigger the asynchrnous
  // shutdown.
  SetTetherTechnologyStateEnabled(false);

  // Tether should be active, but shutting down.
  VerifyTetherActiveStatus(true /* expected_active */);
  EXPECT_EQ(
      TetherComponent::Status::SHUTTING_DOWN,
      test_tether_component_factory_->active_tether_component()->status());

  // Tether should be AVAILABLE.
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));

  // Complete the shutdown process; TetherService should delete its
  // TetherComponent instance.
  test_tether_component_factory_->active_tether_component()
      ->FinishAsynchronousShutdown();
  VerifyTetherActiveStatus(false /* expected_active */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);
}

TEST_F(TetherServiceTest, TestSuspend) {
  CreateTetherService();
  VerifyTetherActiveStatus(true /* expected_active */);

  chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
      power_manager::SuspendImminent_Reason_OTHER);

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  chromeos::FakePowerManagerClient::Get()->SendSuspendDone();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
      power_manager::SuspendImminent_Reason_OTHER);

  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::SUSPENDED,
                                   2 /* expected_count */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_CLOSED_LID);
}

TEST_F(TetherServiceTest, TestDeviceSyncClientNotReady) {
  fake_device_sync_client_ =
      std::make_unique<device_sync::FakeDeviceSyncClient>();

  CreateTetherService();

  fake_device_sync_client_->NotifyReady();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  ShutdownTetherService();
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

TEST_F(TetherServiceTest,
       TestMultiDeviceSetupClientInitiallyHasNoVerifiedHost) {
  fake_tether_host_fetcher_factory_->SetNoInitialDevices();
  initial_feature_state_ = multidevice_setup::mojom::FeatureState::
      kUnavailableNoVerifiedHost_NoEligibleHosts;

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  fake_tether_host_fetcher_factory_->last_created()->set_tether_hosts(
      test_devices_);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kEnabledByUser);

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  ShutdownTetherService();
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

TEST_F(TetherServiceTest, TestMultiDeviceSetupClientLosesVerifiedHost) {
  CreateTetherService();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  fake_tether_host_fetcher_factory_->last_created()->set_tether_hosts({});
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::
          kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified);

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  mock_timer_->Fire();
  ShutdownTetherService();
  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS,
      1 /* expected_count */);
  VerifyLastShutdownReason(
      TetherComponent::ShutdownReason::MULTIDEVICE_HOST_UNVERIFIED);
}

TEST_F(TetherServiceTest, TestBetterTogetherSuiteInitiallyDisabled) {
  initial_feature_state_ =
      multidevice_setup::mojom::FeatureState::kUnavailableSuiteDisabled;

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kEnabledByUser);

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  ShutdownTetherService();
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

TEST_F(TetherServiceTest, TestBetterTogetherSuiteBecomesDisabled) {
  CreateTetherService();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kUnavailableSuiteDisabled);

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  ShutdownTetherService();
  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::BETTER_TOGETHER_SUITE_DISABLED,
      1 /* expected_count */);
  VerifyLastShutdownReason(
      TetherComponent::ShutdownReason::BETTER_TOGETHER_SUITE_DISABLED);
}

TEST_F(TetherServiceTest, TestGet_NotPrimaryUser_FeatureFlagDisabled) {
  EXPECT_FALSE(TetherService::Get(profile_.get()));
}

TEST_F(TetherServiceTest, TestGet_PrimaryUser_FeatureFlagDisabled) {
  SetPrimaryUserLoggedIn();
  EXPECT_FALSE(TetherService::Get(profile_.get()));
}

TEST_F(TetherServiceTest, TestGet_NotPrimaryUser_FeatureFlagEnabled) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(chromeos::features::kInstantTethering);

  EXPECT_FALSE(TetherService::Get(profile_.get()));
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestGet_PrimaryUser_FeatureFlagEnabled) {
  SetPrimaryUserLoggedIn();

  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures(
      {chromeos::features::kInstantTethering} /* enabled_features */,
      {} /* disabled_features */);

  TetherService* tether_service = TetherService::Get(profile_.get());
  ASSERT_TRUE(tether_service);

  base::RunLoop().RunUntilIdle();
  tether_service->Shutdown();

  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(
    TetherServiceTest,
    DISABLED_TestGet_PrimaryUser_FeatureFlagEnabled_MultiDeviceApiFlagEnabled) {
  SetPrimaryUserLoggedIn();

  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures(
      {chromeos::features::kInstantTethering} /* enabled_features */,
      {} /* disabled_features */);

  TetherService* tether_service = TetherService::Get(profile_.get());
  ASSERT_TRUE(tether_service);

  base::RunLoop().RunUntilIdle();
  tether_service->Shutdown();

  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(
    TetherServiceTest,
    DISABLED_TestGet_PrimaryUser_FeatureFlagEnabled_MultiDeviceApiAndMultiDeviceSetupFlagsEnabled) {
  SetPrimaryUserLoggedIn();

  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures(
      {chromeos::features::kInstantTethering} /* enabled_features */,
      {} /* disabled_features */);

  TetherService* tether_service = TetherService::Get(profile_.get());
  ASSERT_TRUE(tether_service);

  fake_multidevice_setup_client_impl_factory_->fake_multidevice_setup_client()
      ->SetFeatureState(multidevice_setup::mojom::Feature::kInstantTethering,
                        multidevice_setup::mojom::FeatureState::kEnabledByUser);

  base::RunLoop().RunUntilIdle();
  tether_service->Shutdown();

  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

TEST_F(TetherServiceTest, TestNoTetherHosts) {
  fake_tether_host_fetcher_factory_->SetNoInitialDevices();
  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  // Simulate this being the final state of Tether by passing time.
  mock_timer_->Fire();

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS,
      1 /* expected_count */);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestProhibitedByPolicy) {
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringAllowedPrefName, false);

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_PROHIBITED,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::PROHIBITED, 1 /* expected_count */);
}

TEST_F(TetherServiceTest, TestBluetoothNotPresent) {
  set_is_adapter_present(false);

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  // Simulate this being the final state of Tether by passing time.
  mock_timer_->Fire();

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::BLE_NOT_PRESENT,
      1 /* expected_count */);
}

TEST_F(TetherServiceTest, TestMetricsFalsePositives) {
  set_is_adapter_present(false);
  fake_tether_host_fetcher_factory_->SetNoInitialDevices();
  CreateTetherService();

  set_is_adapter_present(true);
  SetIsBluetoothPowered(true);

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  fake_tether_host_fetcher_factory_->last_created()->set_tether_hosts(
      test_devices_);
  fake_tether_host_fetcher_factory_->last_created()->NotifyTetherHostsUpdated();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  // No metric should have been recorded for BLE_NOT_PRESENT and
  // NO_AVAILABLE_HOSTS, but ENABLED should have been recorded.
  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::BLE_NOT_PRESENT,
      0 /* expected_count */);
  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS,
      0 /* expected_count */);
  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   1 /* expected_count */);

  // Ensure that the pending state recording has been canceled.
  ASSERT_FALSE(mock_timer_->IsRunning());

  ShutdownTetherService();
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::USER_LOGGED_OUT);
}

TEST_F(TetherServiceTest, TestWifiNotPresent) {
  RemoveWifiFromSystem();

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::WIFI_NOT_PRESENT,
      1 /* expected_count */);
}

TEST_F(TetherServiceTest, TestIsBluetoothPowered) {
  SetIsBluetoothPowered(false);

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  SetIsBluetoothPowered(true);

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  SetIsBluetoothPowered(false);

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::BLUETOOTH_DISABLED,
      2 /* expected_count */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::BLUETOOTH_DISABLED);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestCellularIsUnavailable) {
  manager_test()->RemoveTechnology(shill::kTypeCellular);
  ASSERT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Cellular()));

  CreateTetherService();

  SetTetherTechnologyStateEnabled(false);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);

  SetTetherTechnologyStateEnabled(true);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   2 /* expected_count */);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestCellularIsAvailable) {
  // TODO (lesliewatkins): Investigate why cellular needs to be removed and
  // re-added for NetworkStateHandler to return the correct TechnologyState.
  manager_test()->RemoveTechnology(shill::kTypeCellular);
  manager_test()->AddTechnology(shill::kTypeCellular, false);

  CreateTetherService();

  // Cellular disabled
  SetCellularTechnologyStateEnabled(false);
  ASSERT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Cellular()));
  VerifyTetherActiveStatus(false /* expected_active */);

  SetTetherTechnologyStateEnabled(false);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  SetTetherTechnologyStateEnabled(true);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  // Cellular enabled
  SetCellularTechnologyStateEnabled(true);
  ASSERT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Cellular()));
  VerifyTetherActiveStatus(true /* expected_active */);

  SetTetherTechnologyStateEnabled(false);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);

  SetTetherTechnologyStateEnabled(true);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  SetCellularTechnologyStateEnabled(false);

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::CELLULAR_DISABLED,
      2 /* expected_count */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::CELLULAR_DISABLED);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestDisabled) {
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, false);

  CreateTetherService();

  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName));
  VerifyTetherActiveStatus(false /* expected_active */);

  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::USER_PREFERENCE_DISABLED,
      1 /* expected_count */);
}

// TODO(https://crbug.com/893878): Fix disabled test.
TEST_F(TetherServiceTest, DISABLED_TestEnabled) {
  CreateTetherService();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  SetTetherTechnologyStateEnabled(false);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  EXPECT_FALSE(profile_->GetPrefs()->GetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName));
  VerifyTetherActiveStatus(false /* expected_active */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", false,
      1u /* expected_count */);

  SetTetherTechnologyStateEnabled(true);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  EXPECT_TRUE(profile_->GetPrefs()->GetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName));
  VerifyTetherActiveStatus(true /* expected_active */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", true,
      1u /* expected_count */);

  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   2 /* expected_count */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);
}

TEST_F(TetherServiceTest, TestUserPrefChangesViaFeatureStateChange) {
  // Start with the feature disabled.
  initial_feature_state_ =
      multidevice_setup::mojom::FeatureState::kDisabledByUser;
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, false);
  CreateTetherService();

  // Enable the feature.
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, true);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kEnabledByUser);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);
  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   1 /* expected_count */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", true,
      1u /* expected_count */);

  // Disable the feature.
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, false);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kDisabledByUser);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);
  VerifyTetherFeatureStateRecorded(
      TetherService::TetherFeatureState::USER_PREFERENCE_DISABLED,
      2 /* expected_count */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", false,
      1u /* expected_count */);

  // Enable the feature.
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, true);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kEnabledByUser);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);
  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   2 /* expected_count */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", true,
      2u /* expected_count */);

  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);
}

TEST_F(TetherServiceTest, TestUserPrefChangesViaTechnologyStateChange) {
  CreateTetherService();

  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);

  SetTetherTechnologyStateEnabled(false);
  fake_multidevice_setup_client_->InvokePendingSetFeatureEnabledStateCallback(
      multidevice_setup::mojom::Feature::kInstantTethering,
      false /* expected_enabled */, absl::nullopt /* expected_auth_token */,
      true /* success */);
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, false);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kDisabledByUser);
  EXPECT_EQ(
      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
      network_state_handler()->GetTechnologyState(
          NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(false /* expected_active */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", false,
      1u /* expected_count */);

  SetTetherTechnologyStateEnabled(true);
  fake_multidevice_setup_client_->InvokePendingSetFeatureEnabledStateCallback(
      multidevice_setup::mojom::Feature::kInstantTethering,
      true /* expected_enabled */, absl::nullopt /* expected_auth_token */,
      false /* success */);
  profile_->GetPrefs()->SetBoolean(
      multidevice_setup::kInstantTetheringEnabledPrefName, true);
  fake_multidevice_setup_client_->SetFeatureState(
      multidevice_setup::mojom::Feature::kInstantTethering,
      multidevice_setup::mojom::FeatureState::kEnabledByUser);
  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
            network_state_handler()->GetTechnologyState(
                NetworkTypePattern::Tether()));
  VerifyTetherActiveStatus(true /* expected_active */);
  histogram_tester_.ExpectBucketCount(
      "InstantTethering.UserPreference.OnToggle", true,
      1u /* expected_count */);

  VerifyTetherFeatureStateRecorded(TetherService::TetherFeatureState::ENABLED,
                                   2 /* expected_count */);
  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);
}

// TODO(https://crbug.com/893878): Fix disabled test.
// Test against a past defect that made TetherService and NetworkStateHandler
// repeatly update technology state after the other did so. TetherService should
// only update technology state if NetworkStateHandler has provided a different
// state than the user preference.
TEST_F(TetherServiceTest, DISABLED_TestEnabledMultipleChanges) {
  CreateTetherService();

  // CreateTetherService calls RunUntilIdle() so UpdateTetherTechnologyState()
  // may be called multiple times in the initialization process.
  int updated_technology_state_count =
      tether_service_->updated_technology_state_count();

  SetTetherTechnologyStateEnabled(false);
  SetTetherTechnologyStateEnabled(false);
  SetTetherTechnologyStateEnabled(false);

  updated_technology_state_count++;
  EXPECT_EQ(updated_technology_state_count,
            tether_service_->updated_technology_state_count());

  SetTetherTechnologyStateEnabled(true);
  SetTetherTechnologyStateEnabled(true);
  SetTetherTechnologyStateEnabled(true);

  updated_technology_state_count++;
  EXPECT_EQ(updated_technology_state_count,
            tether_service_->updated_technology_state_count());

  VerifyLastShutdownReason(TetherComponent::ShutdownReason::PREF_DISABLED);
}

}  // namespace tether
}  // namespace ash
