// Copyright 2018 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 "chromeos/components/tether/connection_preserver_impl.h"

#include <memory>

#include "base/base64.h"
#include "base/memory/ptr_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/timer/mock_timer.h"
#include "chromeos/components/multidevice/remote_device_test_util.h"
#include "chromeos/components/tether/fake_active_host.h"
#include "chromeos/components/tether/mock_tether_host_response_recorder.h"
#include "chromeos/components/tether/timer_factory.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_state_test.h"
#include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h"
#include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h"
#include "chromeos/services/secure_channel/public/cpp/client/fake_connection_attempt.h"
#include "chromeos/services/secure_channel/public/cpp/client/fake_secure_channel_client.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using testing::_;
using testing::NiceMock;
using testing::Return;

namespace chromeos {

namespace tether {

namespace {

const char kWifiNetworkGuid[] = "wifiNetworkGuid";
const char kTetherNetworkGuid[] = "tetherNetworkGuid";

std::string CreateConfigurationJsonString(const std::string& guid,
                                          const std::string& type) {
  std::stringstream ss;
  ss << "{"
     << "  \"GUID\": \"" << guid << "\","
     << "  \"Type\": \"" << type << "\","
     << "  \"State\": \"" << shill::kStateReady << "\""
     << "}";
  return ss.str();
}

}  // namespace

class ConnectionPreserverImplTest : public NetworkStateTest {
 protected:
  ConnectionPreserverImplTest()
      : test_local_device_(multidevice::RemoteDeviceRefBuilder()
                               .SetPublicKey("local device")
                               .Build()),
        test_remote_devices_(multidevice::CreateRemoteDeviceRefListForTest(3)) {
    std::transform(
        test_remote_devices_.begin(), test_remote_devices_.end(),
        std::back_inserter(test_remote_device_ids_),
        [](const auto& remote_device) { return remote_device.GetDeviceId(); });
  }

  void SetUp() override {
    DBusThreadManager::Initialize();
    NetworkStateTest::SetUp();

    fake_device_sync_client_ =
        std::make_unique<device_sync::FakeDeviceSyncClient>();
    fake_device_sync_client_->set_local_device_metadata(test_local_device_);
    fake_device_sync_client_->set_synced_devices(test_remote_devices_);
    fake_secure_channel_client_ =
        std::make_unique<secure_channel::FakeSecureChannelClient>();

    fake_active_host_ = std::make_unique<FakeActiveHost>();

    previously_connected_host_ids_.clear();
    mock_tether_host_response_recorder_ =
        std::make_unique<NiceMock<MockTetherHostResponseRecorder>>();
    ON_CALL(*mock_tether_host_response_recorder_,
            GetPreviouslyConnectedHostIds())
        .WillByDefault(Invoke(
            this, &ConnectionPreserverImplTest::GetPreviouslyConnectedHostIds));

    connection_preserver_ = std::make_unique<ConnectionPreserverImpl>(
        fake_device_sync_client_.get(), fake_secure_channel_client_.get(),
        network_state_handler(), fake_active_host_.get(),
        mock_tether_host_response_recorder_.get());

    mock_timer_ = new base::MockOneShotTimer();
    connection_preserver_->SetTimerForTesting(base::WrapUnique(mock_timer_));
  }

  void TearDown() override {
    connection_preserver_.reset();

    ShutdownNetworkState();
    NetworkStateTest::TearDown();
    DBusThreadManager::Shutdown();
  }

  void SimulateSuccessfulHostScan(multidevice::RemoteDeviceRef remote_device,
                                  bool should_remain_registered) {
    // |connection_preserver_| should only grab |fake_connection_attempt| if
    // it is intended to keep the connection open.
    auto fake_connection_attempt =
        std::make_unique<secure_channel::FakeConnectionAttempt>();
    auto* fake_connection_attempt_raw = fake_connection_attempt.get();
    fake_secure_channel_client_->set_next_listen_connection_attempt(
        remote_device, test_local_device_, std::move(fake_connection_attempt));

    connection_preserver_->HandleSuccessfulTetherAvailabilityResponse(
        remote_device.GetDeviceId());

    // If |connection_preserver_| is not expected to preserve the connection, it
    // should not create a ConnectionAttempt, i.e., |next_connection_attempt|
    // should still be present.
    secure_channel::ConnectionAttempt* next_connection_attempt =
        fake_secure_channel_client_->peek_next_listen_connection_attempt(
            remote_device, test_local_device_);
    if (should_remain_registered) {
      EXPECT_FALSE(next_connection_attempt);
    } else {
      // Expect that |connection_preserver_| did not grab the ConnectionAttempt.
      EXPECT_TRUE(next_connection_attempt);
      // Clean up |next_connection_attempt| or else
      // |fake_secure_channel_client_| will fail a DCHECK when it's destroyed.
      fake_secure_channel_client_->clear_next_listen_connection_attempt(
          remote_device, test_local_device_);
      return;
    }

    auto fake_client_channel =
        std::make_unique<secure_channel::FakeClientChannel>();
    auto* fake_client_channel_raw = fake_client_channel.get();
    fake_client_channel_raw->set_destructor_callback(
        base::BindOnce(&ConnectionPreserverImplTest::OnClientChannelDestroyed,
                       base::Unretained(this), remote_device));

    fake_connection_attempt_raw->NotifyConnection(
        std::move(fake_client_channel));

    // Expect that |connection_preserver_| continues to hold on to the
    // ClientChannel until it is destroyed or the active host becomes connected.
    VerifyChannelForRemoteDeviceDestroyed(remote_device,
                                          false /* expect_destroyed */);
  }

  void VerifyChannelForRemoteDeviceDestroyed(
      multidevice::RemoteDeviceRef remote_device,
      bool expect_destroyed) {
    if (expect_destroyed) {
      EXPECT_TRUE(remote_device_to_client_channel_destruction_count_map_
                      [remote_device]);
    } else {
      EXPECT_FALSE(remote_device_to_client_channel_destruction_count_map_
                       [remote_device]);
    }
  }

  void ConnectToWifi() {
    std::string wifi_service_path = ConfigureService(
        CreateConfigurationJsonString(kWifiNetworkGuid, shill::kTypeWifi));
  }

  std::vector<std::string> GetPreviouslyConnectedHostIds() {
    return previously_connected_host_ids_;
  }

  void OnClientChannelDestroyed(multidevice::RemoteDeviceRef remote_device) {
    remote_device_to_client_channel_destruction_count_map_[remote_device]++;
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;

  const multidevice::RemoteDeviceRef test_local_device_;
  const multidevice::RemoteDeviceRefList test_remote_devices_;
  std::vector<std::string> test_remote_device_ids_;

  base::flat_map<multidevice::RemoteDeviceRef,
                 secure_channel::FakeClientChannel*>
      remote_device_to_fake_client_channel_map_;
  base::flat_map<multidevice::RemoteDeviceRef, int>
      remote_device_to_client_channel_destruction_count_map_;

  std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_;
  std::unique_ptr<secure_channel::FakeSecureChannelClient>
      fake_secure_channel_client_;
  std::unique_ptr<FakeActiveHost> fake_active_host_;
  std::unique_ptr<NiceMock<MockTetherHostResponseRecorder>>
      mock_tether_host_response_recorder_;
  base::MockOneShotTimer* mock_timer_;

  std::unique_ptr<ConnectionPreserverImpl> connection_preserver_;

  std::vector<std::string> previously_connected_host_ids_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ConnectionPreserverImplTest);
};

TEST_F(ConnectionPreserverImplTest,
       TestHandleSuccessfulTetherAvailabilityResponse_NoPreservedConnection) {
  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);
}

TEST_F(ConnectionPreserverImplTest,
       TestHandleSuccessfulTetherAvailabilityResponse_HasInternet) {
  ConnectToWifi();

  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             false /* should_remain_registered */);
}

TEST_F(
    ConnectionPreserverImplTest,
    TestHandleSuccessfulTetherAvailabilityResponse_PreservedConnectionExists_NoPreviouslyConnectedHosts) {
  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        false /* expect_destroyed */);

  SimulateSuccessfulHostScan(test_remote_devices_[1],
                             true /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        true /* expect_destroyed */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[1],
                                        false /* expect_destroyed */);
}

TEST_F(ConnectionPreserverImplTest,
       TestHandleSuccessfulTetherAvailabilityResponse_TimesOut) {
  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);

  mock_timer_->Fire();
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        true /* expect_destroyed */);
}

TEST_F(ConnectionPreserverImplTest,
       TestHandleSuccessfulTetherAvailabilityResponse_PreserverDestroyed) {
  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);

  connection_preserver_.reset();
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        true /* expect_destroyed */);
}

TEST_F(
    ConnectionPreserverImplTest,
    TestHandleSuccessfulTetherAvailabilityResponse_ActiveHostBecomesConnected) {
  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);

  fake_active_host_->SetActiveHostConnecting(test_remote_device_ids_[0],
                                             kTetherNetworkGuid);
  fake_active_host_->SetActiveHostConnected(
      test_remote_device_ids_[0], kTetherNetworkGuid, kWifiNetworkGuid);

  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        true /* expect_destroyed */);
}

TEST_F(
    ConnectionPreserverImplTest,
    TestHandleSuccessfulTetherAvailabilityResponse_PreviouslyConnectedHostsExist) {
  // |test_remote_device_ids_[0]| is the most recently connected device, and
  // should be preferred over any other device.
  previously_connected_host_ids_.push_back(test_remote_device_ids_[0]);
  previously_connected_host_ids_.push_back(test_remote_device_ids_[1]);

  SimulateSuccessfulHostScan(test_remote_devices_[2],
                             true /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[2],
                                        false /* expect_destroyed */);

  SimulateSuccessfulHostScan(test_remote_devices_[1],
                             true /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[2],
                                        true /* expect_destroyed */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[1],
                                        false /* expect_destroyed */);

  SimulateSuccessfulHostScan(test_remote_devices_[0],
                             true /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[1],
                                        true /* expect_destroyed */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        false /* expect_destroyed */);

  SimulateSuccessfulHostScan(test_remote_devices_[1],
                             false /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        false /* expect_destroyed */);

  SimulateSuccessfulHostScan(test_remote_devices_[2],
                             false /* should_remain_registered */);
  VerifyChannelForRemoteDeviceDestroyed(test_remote_devices_[0],
                                        false /* expect_destroyed */);
}

}  // namespace tether

}  // namespace chromeos
