// Copyright 2015 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/proximity_auth/bluetooth_low_energy_connection_finder.h"

#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/cryptauth/connection.h"
#include "components/cryptauth/cryptauth_test_util.h"
#include "components/cryptauth/fake_connection.h"
#include "components/cryptauth/remote_device.h"
#include "components/cryptauth/wire_message.h"
#include "components/proximity_auth/logging/logging.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_bluetooth_discovery_session.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::AtLeast;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
using testing::SaveArg;

using device::BluetoothDevice;
using device::MockBluetoothDevice;

namespace proximity_auth {
namespace {

const char kBLEGattServiceUUID[] = "b3b7e28e-a000-3e17-bd86-6e97b9e28c11";
const char kAdvertisementUUID[] = "0000fe50-0000-1000-8000-00805f9b34fb";
const int8_t kRssi = -30;
const char kEidForPreviousTimeQuantum[] = "\x12\x34";
const char kEidForCurrentTimeQuantum[] = "\xab\xcd";
const char kEidForNextTimeQuantum[] = "\x56\x78";
const char kWrongEid[] = "\xff\xff";
const int64_t kEidPeriodMs = 60 * 1000 * 15;  // 15 minutes.

class MockBluetoothLowEnergyConnectionFinder;
class FakeEidGenerator : public cryptauth::BackgroundEidGenerator {
 public:
  FakeEidGenerator(MockBluetoothLowEnergyConnectionFinder* connection_finder)
      : connection_finder_(connection_finder) {}
  ~FakeEidGenerator() override {}

  std::vector<cryptauth::DataWithTimestamp> GenerateNearestEids(
      const std::vector<cryptauth::BeaconSeed>& beacon_seed) const override;

 private:
  MockBluetoothLowEnergyConnectionFinder* connection_finder_;

  DISALLOW_COPY_AND_ASSIGN(FakeEidGenerator);
};

class MockBluetoothLowEnergyConnectionFinder
    : public BluetoothLowEnergyConnectionFinder {
 public:
  MockBluetoothLowEnergyConnectionFinder()
      : BluetoothLowEnergyConnectionFinder(
            cryptauth::CreateLERemoteDeviceForTest(),
            kBLEGattServiceUUID,
            std::make_unique<FakeEidGenerator>(this)) {}

  ~MockBluetoothLowEnergyConnectionFinder() override {}

  // Mock methods don't support return type std::unique_ptr<>. This is a
  // possible workaround: mock a proxy method to be called by the target
  // overridden method (CreateConnection).
  MOCK_METHOD0(CreateConnectionProxy, cryptauth::Connection*());

  // Creates a mock connection and sets an expectation that the mock connection
  // finder's CreateConnection() method will be called and will return the
  // created connection. Returns a reference to the created connection.
  // NOTE: The returned connection's lifetime is managed by the connection
  // finder.
  cryptauth::FakeConnection* ExpectCreateConnection() {
    std::unique_ptr<cryptauth::FakeConnection> connection(
        new cryptauth::FakeConnection(
            cryptauth::CreateLERemoteDeviceForTest()));
    cryptauth::FakeConnection* connection_alias = connection.get();
    EXPECT_CALL(*this, CreateConnectionProxy())
        .WillOnce(Return(connection.release()));
    return connection_alias;
  }

  void SetNearestEids(const std::vector<std::string>& eids) {
    nearest_eids_ = eids;
  }

  const std::vector<std::string>& nearest_eids() { return nearest_eids_; }

 protected:
  std::unique_ptr<cryptauth::Connection> CreateConnection(
      device::BluetoothDevice* bluetooth_device) override {
    return base::WrapUnique(CreateConnectionProxy());
  }

 private:
  std::vector<std::string> nearest_eids_;

  DISALLOW_COPY_AND_ASSIGN(MockBluetoothLowEnergyConnectionFinder);
};

// Not declared in-line due to dependency on
// MockBluetoothLowEnergyConnectionFinder.
std::vector<cryptauth::DataWithTimestamp> FakeEidGenerator::GenerateNearestEids(
    const std::vector<cryptauth::BeaconSeed>& beacon_seed) const {
  std::vector<std::string> nearest_eids = connection_finder_->nearest_eids();

  std::vector<cryptauth::DataWithTimestamp> eid_data_with_timestamps;
  int64_t start_of_period_ms = 0;
  for (const std::string& eid : nearest_eids) {
    eid_data_with_timestamps.push_back(cryptauth::DataWithTimestamp(
        eid, start_of_period_ms, start_of_period_ms + kEidPeriodMs));
    start_of_period_ms += kEidPeriodMs;
  }

  return eid_data_with_timestamps;
}

}  // namespace

class ProximityAuthBluetoothLowEnergyConnectionFinderTest
    : public testing::Test {
 protected:
  ProximityAuthBluetoothLowEnergyConnectionFinderTest()
      : adapter_(new NiceMock<device::MockBluetoothAdapter>),
        connection_callback_(
            base::Bind(&ProximityAuthBluetoothLowEnergyConnectionFinderTest::
                           OnConnectionFound,
                       base::Unretained(this))),
        device_(new NiceMock<device::MockBluetoothDevice>(
            adapter_.get(),
            0,
            cryptauth::kTestRemoteDeviceName,
            cryptauth::kTestRemoteDeviceBluetoothAddress,
            false,
            false)),
        last_discovery_session_alias_(nullptr) {
    device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);

    std::vector<const device::BluetoothDevice*> devices;
    ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));

    ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
    ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));

    std::vector<std::string> nearest_eids;
    nearest_eids.push_back(kEidForPreviousTimeQuantum);
    nearest_eids.push_back(kEidForCurrentTimeQuantum);
    nearest_eids.push_back(kEidForNextTimeQuantum);
    connection_finder_.SetNearestEids(nearest_eids);
  }

  void OnConnectionFound(std::unique_ptr<cryptauth::Connection> connection) {
    last_found_connection_ = std::move(connection);
  }

  void FindAndExpectStartDiscovery() {
    device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
    std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
        new NiceMock<device::MockBluetoothDiscoverySession>());
    last_discovery_session_alias_ = discovery_session.get();

    // Starting a discovery session. StartDiscoveryWithFilterRaw is a proxy for
    // StartDiscoveryWithFilter.
    EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
        .WillOnce(SaveArg<1>(&discovery_callback));
    EXPECT_CALL(*adapter_, AddObserver(_));
    ON_CALL(*last_discovery_session_alias_, IsActive())
        .WillByDefault(Return(true));
    connection_finder_.Find(connection_callback_);
    ASSERT_FALSE(discovery_callback.is_null());
    discovery_callback.Run(std::move(discovery_session));

    EXPECT_CALL(*adapter_, RemoveObserver(_)).Times(AtLeast(1));
  }

  // Prepare |device_| with the given EID.
  void PrepareDevice(const std::string& eid) {
    PrepareDevice(device_.get(), eid);
  }

  void PrepareDevice(MockBluetoothDevice* device, const std::string& eid) {
    device::BluetoothUUID advertisement_uuid(kAdvertisementUUID);
    std::vector<uint8_t> eid_vector(eid.c_str(), eid.c_str() + eid.length());
    device::BluetoothDevice::UUIDList uuid_list;
    uuid_list.push_back(advertisement_uuid);
    device::BluetoothDevice::ServiceDataMap service_data_map;
    service_data_map[advertisement_uuid] = eid_vector;
    device_->UpdateAdvertisementData(kRssi, uuid_list, service_data_map,
                                     {} /* manufacturer_data */, nullptr);
  }

  scoped_refptr<device::MockBluetoothAdapter> adapter_;
  cryptauth::ConnectionFinder::ConnectionCallback connection_callback_;
  std::unique_ptr<device::MockBluetoothDevice> device_;
  std::unique_ptr<cryptauth::Connection> last_found_connection_;
  device::MockBluetoothDiscoverySession* last_discovery_session_alias_;
  StrictMock<MockBluetoothLowEnergyConnectionFinder> connection_finder_;

 private:
  base::MessageLoop message_loop_;
};

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_StartsDiscoverySession) {
  EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _));
  EXPECT_CALL(*adapter_, AddObserver(_));
  connection_finder_.Find(connection_callback_);
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_StopsDiscoverySessionBeforeDestroying) {
  device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
  std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
      new NiceMock<device::MockBluetoothDiscoverySession>());
  device::MockBluetoothDiscoverySession* discovery_session_alias =
      discovery_session.get();

  EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
      .WillOnce(SaveArg<1>(&discovery_callback));
  ON_CALL(*discovery_session_alias, IsActive()).WillByDefault(Return(true));
  EXPECT_CALL(*adapter_, AddObserver(_));
  connection_finder_.Find(connection_callback_);

  ASSERT_FALSE(discovery_callback.is_null());
  discovery_callback.Run(std::move(discovery_session));

  EXPECT_CALL(*adapter_, RemoveObserver(_));
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_DeviceAdded_EidMatches) {
  FindAndExpectStartDiscovery();

  connection_finder_.ExpectCreateConnection();
  PrepareDevice(kEidForCurrentTimeQuantum);
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_DeviceChanged_EidMatches) {
  FindAndExpectStartDiscovery();

  connection_finder_.DeviceAdded(adapter_.get(), device_.get());

  connection_finder_.ExpectCreateConnection();
  PrepareDevice(kEidForPreviousTimeQuantum);
  connection_finder_.DeviceChanged(adapter_.get(), device_.get());
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_DeviceAdded_EidDoesNotMatch) {
  FindAndExpectStartDiscovery();

  PrepareDevice(kWrongEid);

  EXPECT_CALL(connection_finder_, CreateConnectionProxy()).Times(0);
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_DeviceChanged_EidDoesNotMatch) {
  FindAndExpectStartDiscovery();

  PrepareDevice(kWrongEid);
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());

  EXPECT_CALL(connection_finder_, CreateConnectionProxy()).Times(0);
  connection_finder_.DeviceChanged(adapter_.get(), device_.get());
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_CreatesOnlyOneConnection) {
  FindAndExpectStartDiscovery();

  // Prepare first device with valid EID.
  PrepareDevice(kEidForCurrentTimeQuantum);

  // Prepare second device with valid EID.
  NiceMock<device::MockBluetoothDevice> other_device(
      adapter_.get(), 0, cryptauth::kTestRemoteDeviceName,
      cryptauth::kTestRemoteDeviceBluetoothAddress, false, false);
  PrepareDevice(&other_device, kEidForPreviousTimeQuantum);

  // Add the devices. Only one connection is expected.
  connection_finder_.ExpectCreateConnection();
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());
  connection_finder_.DeviceAdded(adapter_.get(), &other_device);
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_EidMatches_ConnectionSucceeds) {
  // Starting discovery.
  FindAndExpectStartDiscovery();

  // Finding and creating a connection to the right device.
  cryptauth::FakeConnection* connection =
      connection_finder_.ExpectCreateConnection();
  PrepareDevice(kEidForCurrentTimeQuantum);
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());

  // Creating a connection.
  base::RunLoop run_loop;
  EXPECT_FALSE(last_found_connection_);
  connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
  connection->SetStatus(cryptauth::Connection::CONNECTED);
  run_loop.RunUntilIdle();
  EXPECT_TRUE(last_found_connection_);
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_ConnectionFails_RestartDiscoveryAndConnectionSucceeds) {
  // Starting discovery.
  FindAndExpectStartDiscovery();

  // Preparing to create a GATT connection to the right device.
  PrepareDevice(kEidForNextTimeQuantum);
  cryptauth::FakeConnection* connection =
      connection_finder_.ExpectCreateConnection();

  // Trying to create a connection.
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());
  ASSERT_FALSE(last_found_connection_);
  connection->SetStatus(cryptauth::Connection::IN_PROGRESS);

  // Preparing to restart the discovery session.
  device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
  std::vector<const device::BluetoothDevice*> devices;
  ON_CALL(*adapter_, GetDevices()).WillByDefault(Return(devices));
  EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
      .WillOnce(SaveArg<1>(&discovery_callback));

  // Connection fails.
  {
    base::RunLoop run_loop;
    connection->SetStatus(cryptauth::Connection::DISCONNECTED);
    run_loop.RunUntilIdle();
  }

  // Restarting the discovery session.
  std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
      new NiceMock<device::MockBluetoothDiscoverySession>());
  last_discovery_session_alias_ = discovery_session.get();
  ON_CALL(*last_discovery_session_alias_, IsActive())
      .WillByDefault(Return(true));
  ASSERT_FALSE(discovery_callback.is_null());
  discovery_callback.Run(std::move(discovery_session));

  // Connect again.
  PrepareDevice(kEidForNextTimeQuantum);
  connection = connection_finder_.ExpectCreateConnection();
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());

  // Completing the connection.
  {
    base::RunLoop run_loop;
    EXPECT_FALSE(last_found_connection_);
    connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
    connection->SetStatus(cryptauth::Connection::CONNECTED);
    run_loop.RunUntilIdle();
  }
  EXPECT_TRUE(last_found_connection_);
}

TEST_F(ProximityAuthBluetoothLowEnergyConnectionFinderTest,
       Find_AdapterRemoved_RestartDiscoveryAndConnectionSucceeds) {
  // Starting discovery.
  FindAndExpectStartDiscovery();

  // Removing the adapter.
  ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(false));
  ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(false));
  ON_CALL(*last_discovery_session_alias_, IsActive())
      .WillByDefault(Return(false));
  connection_finder_.AdapterPoweredChanged(adapter_.get(), false);
  connection_finder_.AdapterPresentChanged(adapter_.get(), false);

  // Adding the adapter.
  ON_CALL(*adapter_, IsPresent()).WillByDefault(Return(true));
  ON_CALL(*adapter_, IsPowered()).WillByDefault(Return(true));

  device::BluetoothAdapter::DiscoverySessionCallback discovery_callback;
  std::unique_ptr<device::MockBluetoothDiscoverySession> discovery_session(
      new NiceMock<device::MockBluetoothDiscoverySession>());
  last_discovery_session_alias_ = discovery_session.get();

  // Restarting the discovery session.
  EXPECT_CALL(*adapter_, StartDiscoverySessionWithFilterRaw(_, _, _))
      .WillOnce(SaveArg<1>(&discovery_callback));
  connection_finder_.AdapterPresentChanged(adapter_.get(), true);
  connection_finder_.AdapterPoweredChanged(adapter_.get(), true);
  ON_CALL(*last_discovery_session_alias_, IsActive())
      .WillByDefault(Return(true));

  ASSERT_FALSE(discovery_callback.is_null());
  discovery_callback.Run(std::move(discovery_session));

  // Preparing to create a GATT connection to the right device.
  PrepareDevice(kEidForPreviousTimeQuantum);
  cryptauth::FakeConnection* connection =
      connection_finder_.ExpectCreateConnection();

  // Trying to create a connection.
  connection_finder_.DeviceAdded(adapter_.get(), device_.get());

  // Completing the connection.
  base::RunLoop run_loop;
  ASSERT_FALSE(last_found_connection_);
  connection->SetStatus(cryptauth::Connection::IN_PROGRESS);
  connection->SetStatus(cryptauth::Connection::CONNECTED);
  run_loop.RunUntilIdle();
  EXPECT_TRUE(last_found_connection_);
}

}  // namespace proximity_auth
