// 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 "device/fido/ble/fido_ble_connection.h"

#include <bitset>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/bluetooth_test.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/mock_bluetooth_device.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_characteristic.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_connection.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_notify_session.h"
#include "device/bluetooth/test/mock_bluetooth_gatt_service.h"
#include "device/fido/ble/fido_ble_uuids.h"
#include "device/fido/test_callback_receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_ANDROID)
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif defined(OS_MACOSX)
#include "device/bluetooth/test/bluetooth_test_mac.h"
#elif defined(OS_WIN)
#include "device/bluetooth/test/bluetooth_test_win.h"
#elif defined(OS_CHROMEOS) || defined(OS_LINUX)
#include "device/bluetooth/test/bluetooth_test_bluez.h"
#elif defined(OS_FUCHSIA)
#include "device/bluetooth/test/bluetooth_test_fuchsia.h"
#endif

namespace device {

using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::Return;

using NiceMockBluetoothAdapter = ::testing::NiceMock<MockBluetoothAdapter>;
using NiceMockBluetoothDevice = ::testing::NiceMock<MockBluetoothDevice>;
using NiceMockBluetoothGattService =
    ::testing::NiceMock<MockBluetoothGattService>;
using NiceMockBluetoothGattCharacteristic =
    ::testing::NiceMock<MockBluetoothGattCharacteristic>;
using NiceMockBluetoothGattConnection =
    ::testing::NiceMock<MockBluetoothGattConnection>;
using NiceMockBluetoothGattNotifySession =
    ::testing::NiceMock<MockBluetoothGattNotifySession>;

namespace {

constexpr auto kDefaultServiceRevision =
    static_cast<uint8_t>(FidoBleConnection::ServiceRevision::kFido2);

std::vector<uint8_t> ToByteVector(base::StringPiece str) {
  return std::vector<uint8_t>(str.begin(), str.end());
}

BluetoothDevice* GetMockDevice(MockBluetoothAdapter* adapter,
                               const std::string& address) {
  const std::vector<BluetoothDevice*> devices = adapter->GetMockDevices();
  auto found = std::find_if(devices.begin(), devices.end(),
                            [&address](const auto* device) {
                              return device->GetAddress() == address;
                            });
  return found != devices.end() ? *found : nullptr;
}

class TestReadCallback {
 public:
  void OnRead(std::vector<uint8_t> value) {
    value_ = std::move(value);
    run_loop_->Quit();
  }

  const std::vector<uint8_t> WaitForResult() {
    run_loop_->Run();
    run_loop_.emplace();
    return value_;
  }

  FidoBleConnection::ReadCallback GetCallback() {
    return base::BindRepeating(&TestReadCallback::OnRead,
                               base::Unretained(this));
  }

 private:
  std::vector<uint8_t> value_;
  base::Optional<base::RunLoop> run_loop_{base::in_place};
};

using TestConnectionCallbackReceiver = test::ValueCallbackReceiver<bool>;

using TestReadControlPointLengthCallback =
    test::ValueCallbackReceiver<base::Optional<uint16_t>>;

using TestReadServiceRevisionsCallback =
    test::ValueCallbackReceiver<std::set<FidoBleConnection::ServiceRevision>>;

using TestWriteCallback = test::ValueCallbackReceiver<bool>;
}  // namespace

class FidoBleConnectionTest : public ::testing::Test {
 public:
  FidoBleConnectionTest() {
    ON_CALL(*adapter_, GetDevice(_))
        .WillByDefault(Invoke([this](const std::string& address) {
          return GetMockDevice(adapter_.get(), address);
        }));

    BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
  }

  BluetoothAdapter* adapter() { return adapter_.get(); }
  MockBluetoothDevice* device() { return fido_device_; }

  void AddFidoDevice(const std::string& device_address) {
    auto fido_device = std::make_unique<NiceMockBluetoothDevice>(
        adapter_.get(), /* bluetooth_class */ 0u,
        BluetoothTest::kTestDeviceNameU2f, device_address, /* paired */ true,
        /* connected */ false);
    fido_device_ = fido_device.get();
    adapter_->AddMockDevice(std::move(fido_device));

    ON_CALL(*fido_device_, GetGattServices())
        .WillByDefault(
            Invoke(fido_device_, &MockBluetoothDevice::GetMockServices));

    ON_CALL(*fido_device_, GetGattService(_))
        .WillByDefault(
            Invoke(fido_device_, &MockBluetoothDevice::GetMockService));
    AddFidoService();
  }

  void SetupConnectingFidoDevice(const std::string& device_address) {
    ON_CALL(*fido_device_, CreateGattConnection)
        .WillByDefault(
            Invoke([this, &device_address](const auto& callback, auto&&) {
              connection_ =
                  new NiceMockBluetoothGattConnection(adapter_, device_address);
              callback.Run(std::move(base::WrapUnique(connection_)));
            }));

    ON_CALL(*fido_device_, IsGattServicesDiscoveryComplete)
        .WillByDefault(Return(true));

    ON_CALL(*fido_service_revision_bitfield_, ReadRemoteCharacteristic)
        .WillByDefault(Invoke([=](auto&& callback, auto&&) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              base::BindOnce(callback,
                             std::vector<uint8_t>({kDefaultServiceRevision})));
        }));

    ON_CALL(*fido_service_revision_bitfield_, WriteRemoteCharacteristic)
        .WillByDefault(Invoke([=](auto&&, auto&& callback, auto&&) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
        }));

    ON_CALL(*fido_status_, StartNotifySession(_, _))
        .WillByDefault(Invoke([this](const auto& callback, auto&&) {
          notify_session_ = new NiceMockBluetoothGattNotifySession(
              fido_status_->GetWeakPtr());
          callback.Run(base::WrapUnique(notify_session_));
        }));
  }

  void SimulateGattDiscoveryComplete(bool complete) {
    EXPECT_CALL(*fido_device_, IsGattServicesDiscoveryComplete)
        .WillOnce(Return(complete));
  }

  void SimulateGattConnectionError() {
    EXPECT_CALL(*fido_device_, CreateGattConnection)
        .WillOnce(Invoke([](auto&&, auto&& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              base::BindOnce(error_callback, BluetoothDevice::ERROR_FAILED));
        }));
  }

  void SimulateGattNotifySessionStartError() {
    EXPECT_CALL(*fido_status_, StartNotifySession(_, _))
        .WillOnce(Invoke([](auto&&, auto&& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              base::BindOnce(error_callback,
                             BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void NotifyStatusChanged(const std::vector<uint8_t>& value) {
    for (auto& observer : adapter_->GetObservers())
      observer.GattCharacteristicValueChanged(adapter_.get(), fido_status_,
                                              value);
  }

  void NotifyGattServicesDiscovered() {
    adapter_->NotifyGattServicesDiscovered(fido_device_);
  }

  void ChangeDeviceAddressAndNotifyObservers(std::string new_address) {
    auto old_address = fido_device_->GetAddress();
    EXPECT_CALL(*fido_device_, GetAddress)
        .WillRepeatedly(::testing::Return(new_address));
    for (auto& observer : adapter_->GetObservers())
      observer.DeviceAddressChanged(adapter_.get(), fido_device_,
                                    std::move(old_address));
  }

  void SetNextReadControlPointLengthReponse(bool success,
                                            const std::vector<uint8_t>& value) {
    EXPECT_CALL(*fido_control_point_length_, ReadRemoteCharacteristic(_, _))
        .WillOnce(Invoke([success, value](const auto& callback,
                                          const auto& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              success
                  ? base::BindOnce(callback, value)
                  : base::BindOnce(error_callback,
                                   BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void SetNextReadServiceRevisionResponse(bool success,
                                          const std::vector<uint8_t>& value) {
    EXPECT_CALL(*fido_service_revision_, ReadRemoteCharacteristic(_, _))
        .WillOnce(Invoke([success, value](const auto& callback,
                                          const auto& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              success
                  ? base::BindOnce(callback, value)
                  : base::BindOnce(error_callback,
                                   BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void SetNextReadServiceRevisionBitfieldResponse(
      bool success,
      const std::vector<uint8_t>& value) {
    EXPECT_CALL(*fido_service_revision_bitfield_,
                ReadRemoteCharacteristic(_, _))
        .WillOnce(Invoke([success, value](const auto& callback,
                                          const auto& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              success
                  ? base::BindOnce(callback, value)
                  : base::BindOnce(error_callback,
                                   BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void SetNextWriteControlPointResponse(bool success) {
// For performance reasons we try writes without responses first on macOS.
#if defined(OS_MACOSX)
    EXPECT_CALL(*fido_control_point_, WriteWithoutResponse)
        .WillOnce(Return(success));
    if (success)
      return;
#else
    EXPECT_CALL(*fido_control_point_, WriteWithoutResponse).Times(0);
#endif  // defined(OS_MACOSX)

    EXPECT_CALL(*fido_control_point_, WriteRemoteCharacteristic(_, _, _))
        .WillOnce(Invoke([success](const auto& data, const auto& callback,
                                   const auto& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              success
                  ? base::BindOnce(callback)
                  : base::BindOnce(error_callback,
                                   BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void SetNextWriteServiceRevisionResponse(std::vector<uint8_t> expected_data,
                                           bool success) {
    EXPECT_CALL(*fido_service_revision_bitfield_,
                WriteRemoteCharacteristic(expected_data, _, _))
        .WillOnce(Invoke([success](const auto& data, const auto& callback,
                                   const auto& error_callback) {
          base::ThreadTaskRunnerHandle::Get()->PostTask(
              FROM_HERE,
              success
                  ? base::BindOnce(callback)
                  : base::BindOnce(error_callback,
                                   BluetoothGattService::GATT_ERROR_FAILED));
        }));
  }

  void AddFidoService() {
    auto fido_service = std::make_unique<NiceMockBluetoothGattService>(
        fido_device_, "fido_service", BluetoothUUID(kFidoServiceUUID),
        /* is_primary */ true, /* is_local */ false);
    fido_service_ = fido_service.get();
    fido_device_->AddMockService(std::move(fido_service));

    static constexpr bool kIsLocal = false;
    {
      auto fido_control_point =
          std::make_unique<NiceMockBluetoothGattCharacteristic>(
              fido_service_, "fido_control_point",
              BluetoothUUID(kFidoControlPointUUID), kIsLocal,
              BluetoothGattCharacteristic::PROPERTY_WRITE,
              BluetoothGattCharacteristic::PERMISSION_NONE);
      fido_control_point_ = fido_control_point.get();
      fido_service_->AddMockCharacteristic(std::move(fido_control_point));
    }

    {
      auto fido_status = std::make_unique<NiceMockBluetoothGattCharacteristic>(
          fido_service_, "fido_status", BluetoothUUID(kFidoStatusUUID),
          kIsLocal, BluetoothGattCharacteristic::PROPERTY_NOTIFY,
          BluetoothGattCharacteristic::PERMISSION_NONE);
      fido_status_ = fido_status.get();
      fido_service_->AddMockCharacteristic(std::move(fido_status));
    }

    {
      auto fido_control_point_length =
          std::make_unique<NiceMockBluetoothGattCharacteristic>(
              fido_service_, "fido_control_point_length",
              BluetoothUUID(kFidoControlPointLengthUUID), kIsLocal,
              BluetoothGattCharacteristic::PROPERTY_READ,
              BluetoothGattCharacteristic::PERMISSION_NONE);
      fido_control_point_length_ = fido_control_point_length.get();
      fido_service_->AddMockCharacteristic(
          std::move(fido_control_point_length));
    }

    {
      auto fido_service_revision =
          std::make_unique<NiceMockBluetoothGattCharacteristic>(
              fido_service_, "fido_service_revision",
              BluetoothUUID(kFidoServiceRevisionUUID), kIsLocal,
              BluetoothGattCharacteristic::PROPERTY_READ,
              BluetoothGattCharacteristic::PERMISSION_NONE);
      fido_service_revision_ = fido_service_revision.get();
      fido_service_->AddMockCharacteristic(std::move(fido_service_revision));
    }

    {
      auto fido_service_revision_bitfield =
          std::make_unique<NiceMockBluetoothGattCharacteristic>(
              fido_service_, "fido_service_revision_bitfield",
              BluetoothUUID(kFidoServiceRevisionBitfieldUUID), kIsLocal,
              BluetoothGattCharacteristic::PROPERTY_READ |
                  BluetoothGattCharacteristic::PROPERTY_WRITE,
              BluetoothGattCharacteristic::PERMISSION_NONE);
      fido_service_revision_bitfield_ = fido_service_revision_bitfield.get();
      fido_service_->AddMockCharacteristic(
          std::move(fido_service_revision_bitfield));
    }
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  scoped_refptr<MockBluetoothAdapter> adapter_ =
      base::MakeRefCounted<NiceMockBluetoothAdapter>();

  MockBluetoothDevice* fido_device_;
  MockBluetoothGattService* fido_service_;

  MockBluetoothGattCharacteristic* fido_control_point_;
  MockBluetoothGattCharacteristic* fido_status_;
  MockBluetoothGattCharacteristic* fido_control_point_length_;
  MockBluetoothGattCharacteristic* fido_service_revision_;
  MockBluetoothGattCharacteristic* fido_service_revision_bitfield_;

  MockBluetoothGattConnection* connection_;
  MockBluetoothGattNotifySession* notify_session_;
};

TEST_F(FidoBleConnectionTest, Address) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  FidoBleConnection connection(adapter(), device_address, base::DoNothing());
  connection.Connect(base::DoNothing());
  EXPECT_EQ(device_address, connection.address());
}

TEST_F(FidoBleConnectionTest, DeviceNotPresent) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, PreConnected) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address, base::DoNothing());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, NoConnectionWithoutCompletedGattDiscovery) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address, base::DoNothing());

  SimulateGattDiscoveryComplete(false);
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(connection_callback_receiver.was_called());

  NotifyGattServicesDiscovered();
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, GattServicesDiscoveredIgnoredBeforeConnection) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());
  NotifyGattServicesDiscovered();

  SimulateGattDiscoveryComplete(false);
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(connection_callback_receiver.was_called());

  NotifyGattServicesDiscovered();
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, GattServicesDiscoveredAgain) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  NotifyGattServicesDiscovered();
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());

  // A second call to the event handler should not trigger another attempt to
  // obtain Gatt Services.
  EXPECT_CALL(*device(), GetGattServices).Times(0);
  EXPECT_CALL(*device(), GetGattService).Times(0);
  NotifyGattServicesDiscovered();
}

TEST_F(FidoBleConnectionTest, SimulateGattConnectionError) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address, base::DoNothing());

  SimulateGattConnectionError();
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, SimulateGattNotifySessionStartError) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  SimulateGattNotifySessionStartError();
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, MultipleServiceRevisions) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);

  static constexpr struct {
    std::bitset<8> supported_revisions;
    std::bitset<8> selected_revision;
  } test_cases[] = {
      // Only U2F 1.1 is supported, pick it.
      {0b1000'0000, 0b1000'0000},
      // Only U2F 1.2 is supported, pick it.
      {0b0100'0000, 0b0100'0000},
      // U2F 1.1 and U2F 1.2 are supported, pick U2F 1.2.
      {0b1100'0000, 0b0100'0000},
      // Only FIDO2 is supported, pick it.
      {0b0010'0000, 0b0010'0000},
      // U2F 1.1 and FIDO2 are supported, pick FIDO2.
      {0b1010'0000, 0b0010'0000},
      // U2F 1.2 and FIDO2 are supported, pick FIDO2.
      {0b0110'0000, 0b0010'0000},
      // U2F 1.1, U2F 1.2 and FIDO2 are supported, pick FIDO2.
      {0b1110'0000, 0b0010'0000},
      // U2F 1.1 and a future revision are supported, pick U2F 1.1.
      {0b1000'1000, 0b1000'0000},
      // U2F 1.2 and a future revision are supported, pick U2F 1.2.
      {0b0100'1000, 0b0100'0000},
      // FIDO2 and a future revision are supported, pick FIDO2.
      {0b0010'1000, 0b0010'0000},
  };

  for (const auto& test_case : test_cases) {
    SCOPED_TRACE(::testing::Message()
                 << "Supported Revisions: " << test_case.supported_revisions
                 << ", Selected Revision: " << test_case.selected_revision);
    SetNextReadServiceRevisionBitfieldResponse(
        true, {test_case.supported_revisions.to_ulong()});

    SetNextWriteServiceRevisionResponse(
        {test_case.selected_revision.to_ulong()}, true);

    FidoBleConnection connection(adapter(), device_address,
                                 base::DoNothing());
    TestConnectionCallbackReceiver connection_callback_receiver;
    connection.Connect(connection_callback_receiver.callback());
    connection_callback_receiver.WaitForCallback();
    EXPECT_TRUE(connection_callback_receiver.value());
  }
}

TEST_F(FidoBleConnectionTest, UnsupportedServiceRevisions) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);

  // Test failure cases.
  static constexpr struct {
    std::bitset<8> supported_revisions;
  } test_cases[] = {
      {0b0000'0000},  // No Service Revision.
      {0b0001'0000},  // Unsupported Service Revision (4th bit).
      {0b0000'1000},  // Unsupported Service Revision (3th bit).
      {0b0000'0100},  // Unsupported Service Revision (2th bit).
      {0b0000'0010},  // Unsupported Service Revision (1th bit).
      {0b0000'0001},  // Unsupported Service Revision (0th bit).
  };

  for (const auto& test_case : test_cases) {
    SCOPED_TRACE(::testing::Message()
                 << "Supported Revisions: " << test_case.supported_revisions);
    SetNextReadServiceRevisionBitfieldResponse(
        true, {test_case.supported_revisions.to_ulong()});

    FidoBleConnection connection(adapter(), device_address,
                                 base::DoNothing());
    TestConnectionCallbackReceiver connection_callback_receiver;
    connection.Connect(connection_callback_receiver.callback());
    connection_callback_receiver.WaitForCallback();
    EXPECT_FALSE(connection_callback_receiver.value());
  }
}

TEST_F(FidoBleConnectionTest, ReadServiceRevisionsFails) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;

  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  SetNextReadServiceRevisionBitfieldResponse(false, {});

  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, WriteServiceRevisionsFails) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;

  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  SetNextReadServiceRevisionBitfieldResponse(true, {kDefaultServiceRevision});
  SetNextWriteServiceRevisionResponse({kDefaultServiceRevision}, false);

  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());
}

TEST_F(FidoBleConnectionTest, ReadStatusNotifications) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  TestReadCallback read_callback;

  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               read_callback.GetCallback());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());

  std::vector<uint8_t> payload = ToByteVector("foo");
  NotifyStatusChanged(payload);
  EXPECT_EQ(payload, read_callback.WaitForResult());

  payload = ToByteVector("bar");
  NotifyStatusChanged(payload);
  EXPECT_EQ(payload, read_callback.WaitForResult());
}

TEST_F(FidoBleConnectionTest, ReadControlPointLength) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());

  {
    TestReadControlPointLengthCallback length_callback;
    SetNextReadControlPointLengthReponse(false, {});
    connection.ReadControlPointLength(length_callback.callback());
    length_callback.WaitForCallback();
    EXPECT_EQ(base::nullopt, length_callback.value());
  }

  // The Control Point Length should consist of exactly two bytes, hence we
  // EXPECT_EQ(base::nullopt) for payloads of size 0, 1 and 3.
  {
    TestReadControlPointLengthCallback length_callback;
    SetNextReadControlPointLengthReponse(true, {});
    connection.ReadControlPointLength(length_callback.callback());
    length_callback.WaitForCallback();
    EXPECT_EQ(base::nullopt, length_callback.value());
  }

  {
    TestReadControlPointLengthCallback length_callback;
    SetNextReadControlPointLengthReponse(true, {0xAB});
    connection.ReadControlPointLength(length_callback.callback());
    length_callback.WaitForCallback();
    EXPECT_EQ(base::nullopt, length_callback.value());
  }

  {
    TestReadControlPointLengthCallback length_callback;
    SetNextReadControlPointLengthReponse(true, {0xAB, 0xCD});
    connection.ReadControlPointLength(length_callback.callback());
    length_callback.WaitForCallback();
    EXPECT_EQ(0xABCD, *length_callback.value());
  }

  {
    TestReadControlPointLengthCallback length_callback;
    SetNextReadControlPointLengthReponse(true, {0xAB, 0xCD, 0xEF});
    connection.ReadControlPointLength(length_callback.callback());
    length_callback.WaitForCallback();
    EXPECT_EQ(base::nullopt, length_callback.value());
  }
}

TEST_F(FidoBleConnectionTest, WriteControlPoint) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_TRUE(connection_callback_receiver.value());

  {
    TestWriteCallback write_callback;
    SetNextWriteControlPointResponse(false);
    connection.WriteControlPoint({}, write_callback.callback());
    write_callback.WaitForCallback();
    EXPECT_FALSE(write_callback.value());
  }

  {
    TestWriteCallback write_callback;
    SetNextWriteControlPointResponse(true);
    connection.WriteControlPoint({}, write_callback.callback());
    write_callback.WaitForCallback();
    EXPECT_TRUE(write_callback.value());
  }
}

TEST_F(FidoBleConnectionTest, ReadsAndWriteFailWhenDisconnected) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;

  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address,
                               base::DoNothing());

  SimulateGattConnectionError();
  TestConnectionCallbackReceiver connection_callback_receiver;
  connection.Connect(connection_callback_receiver.callback());
  connection_callback_receiver.WaitForCallback();
  EXPECT_FALSE(connection_callback_receiver.value());

  // Reads should always fail on a disconnected device.
  TestReadControlPointLengthCallback length_callback;
  connection.ReadControlPointLength(length_callback.callback());
  length_callback.WaitForCallback();
  EXPECT_EQ(base::nullopt, length_callback.value());

  // Writes should always fail on a disconnected device.
  TestWriteCallback write_callback;
  connection.WriteControlPoint({}, write_callback.callback());
  write_callback.WaitForCallback();
  EXPECT_FALSE(write_callback.value());
}

TEST_F(FidoBleConnectionTest, ConnectionAddressChangeWhenDeviceAddressChanges) {
  const std::string device_address = BluetoothTest::kTestDeviceAddress1;
  static constexpr char kTestDeviceAddress2[] = "test_device_address_2";

  AddFidoDevice(device_address);
  SetupConnectingFidoDevice(device_address);
  FidoBleConnection connection(adapter(), device_address, base::DoNothing());
  ChangeDeviceAddressAndNotifyObservers(kTestDeviceAddress2);
  EXPECT_EQ(kTestDeviceAddress2, connection.address());
}

}  // namespace device
