// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "internal/platform/bluetooth_classic.h"

#include <memory>

#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/time/time.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/logging.h"
#include "internal/platform/single_thread_executor.h"

namespace location {
namespace nearby {
namespace {

using FeatureFlags = FeatureFlags::Flags;

constexpr FeatureFlags kTestCases[] = {
    FeatureFlags{
        .enable_cancellation_flag = true,
    },
    FeatureFlags{
        .enable_cancellation_flag = false,
    },
};

class BluetoothClassicMediumTest
    : public ::testing::TestWithParam<FeatureFlags> {
 protected:
  using DiscoveryCallback = BluetoothClassicMedium::DiscoveryCallback;
  BluetoothClassicMediumTest() {
    env_.Start();
    env_.Reset();
    adapter_a_ = std::make_unique<BluetoothAdapter>();
    adapter_b_ = std::make_unique<BluetoothAdapter>();
    bt_a_ = std::make_unique<BluetoothClassicMedium>(*adapter_a_);
    bt_b_ = std::make_unique<BluetoothClassicMedium>(*adapter_b_);
    adapter_a_->SetName("Device-A");
    adapter_b_->SetName("Device-B");
    adapter_a_->SetStatus(BluetoothAdapter::Status::kEnabled);
    adapter_b_->SetStatus(BluetoothAdapter::Status::kEnabled);
    env_.Sync();
  }
  ~BluetoothClassicMediumTest() override {
    env_.Sync(false);
    adapter_a_->SetStatus(BluetoothAdapter::Status::kDisabled);
    adapter_b_->SetStatus(BluetoothAdapter::Status::kDisabled);
    bt_a_.reset();
    bt_b_.reset();
    env_.Sync(false);
    adapter_a_.reset();
    adapter_b_.reset();
    env_.Reset();
    env_.Stop();
  }

  MediumEnvironment& env_{MediumEnvironment::Instance()};

  std::unique_ptr<BluetoothAdapter> adapter_a_;
  std::unique_ptr<BluetoothAdapter> adapter_b_;
  std::unique_ptr<BluetoothClassicMedium> bt_a_;
  std::unique_ptr<BluetoothClassicMedium> bt_b_;
};

TEST_P(BluetoothClassicMediumTest, CanConnectToService) {
  FeatureFlags feature_flags = GetParam();
  env_.SetFeatureFlags(feature_flags);

  adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
  CountDownLatch found_latch(1);
  BluetoothDevice* discovered_device = nullptr;
  bt_a_->StartDiscovery(DiscoveryCallback{
      .device_discovered_cb =
          [this, &found_latch, &discovered_device](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            discovered_device = &device;
            found_latch.CountDown();
          },
  });
  adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_EQ(adapter_b_->GetScanMode(),
            BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
  std::string service_name{"service"};
  std::string service_uuid("service-uuid");
  BluetoothServerSocket server_socket =
      bt_b_->ListenForService(service_name, service_uuid);
  EXPECT_TRUE(server_socket.IsValid());
  BluetoothSocket socket_a;
  BluetoothSocket socket_b;
  EXPECT_FALSE(socket_a.IsValid());
  EXPECT_FALSE(socket_b.IsValid());
  {
    CancellationFlag flag;
    SingleThreadExecutor server_executor;
    SingleThreadExecutor client_executor;
    client_executor.Execute([this, &socket_a, discovered_device, &service_uuid,
                             &server_socket, &flag]() {
      socket_a =
          bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
      if (!socket_a.IsValid()) server_socket.Close();
    });
    server_executor.Execute([&socket_b, &server_socket]() {
      socket_b = server_socket.Accept();
      if (!socket_b.IsValid()) server_socket.Close();
    });
  }
  EXPECT_TRUE(socket_a.IsValid());
  EXPECT_TRUE(socket_b.IsValid());
  server_socket.Close();
}

TEST_P(BluetoothClassicMediumTest, CanCancelConnect) {
  FeatureFlags feature_flags = GetParam();
  env_.SetFeatureFlags(feature_flags);

  adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
  CountDownLatch found_latch(1);
  BluetoothDevice* discovered_device = nullptr;
  bt_a_->StartDiscovery(DiscoveryCallback{
      .device_discovered_cb =
          [this, &found_latch, &discovered_device](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            discovered_device = &device;
            found_latch.CountDown();
          },
  });
  adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_EQ(adapter_b_->GetScanMode(),
            BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
  std::string service_name{"service"};
  std::string service_uuid("service-uuid");
  BluetoothServerSocket server_socket =
      bt_b_->ListenForService(service_name, service_uuid);
  EXPECT_TRUE(server_socket.IsValid());
  BluetoothSocket socket_a;
  BluetoothSocket socket_b;
  EXPECT_FALSE(socket_a.IsValid());
  EXPECT_FALSE(socket_b.IsValid());
  {
    CancellationFlag flag(true);
    SingleThreadExecutor server_executor;
    SingleThreadExecutor client_executor;
    client_executor.Execute([this, &socket_a, discovered_device, &service_uuid,
                             &server_socket, &flag]() {
      socket_a =
          bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
      if (!socket_a.IsValid()) server_socket.Close();
    });
    server_executor.Execute([&socket_b, &server_socket]() {
      socket_b = server_socket.Accept();
      if (!socket_b.IsValid()) server_socket.Close();
    });
  }
  // If FeatureFlag is disabled, Cancelled is false as no-op.
  if (!feature_flags.enable_cancellation_flag) {
    EXPECT_TRUE(socket_a.IsValid());
    EXPECT_TRUE(socket_b.IsValid());
  } else {
    EXPECT_FALSE(socket_a.IsValid());
    EXPECT_FALSE(socket_b.IsValid());
  }
  server_socket.Close();
}

INSTANTIATE_TEST_SUITE_P(ParametrisedBluetoothClassicMediumTest,
                         BluetoothClassicMediumTest,
                         ::testing::ValuesIn(kTestCases));

TEST_F(BluetoothClassicMediumTest, ConstructorDestructorWorks) {
  // Make sure we can create functional adapters.
  ASSERT_TRUE(adapter_a_->IsValid());
  ASSERT_TRUE(adapter_b_->IsValid());

  // Make sure we can create 2 distinct adapters.
  // NOTE: multiple adapters are supported on a test platform, but not
  // necessarily on every available HW platform.
  // Often, HW platform supports only one BT adapter.
  EXPECT_NE(&adapter_a_->GetImpl(), &adapter_b_->GetImpl());

  // Make sure we can create functional mediums.
  ASSERT_TRUE(bt_a_->IsValid());
  ASSERT_TRUE(bt_b_->IsValid());

  // Make sure we can create 2 distinct mediums.
  EXPECT_NE(&bt_a_->GetImpl(), &bt_b_->GetImpl());
}

TEST_F(BluetoothClassicMediumTest, CanStartDiscovery) {
  adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
  CountDownLatch found_latch(1);
  CountDownLatch lost_latch(1);
  bt_a_->StartDiscovery(DiscoveryCallback{
      .device_discovered_cb =
          [this, &found_latch](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            found_latch.CountDown();
          },
      .device_lost_cb =
          [this, &lost_latch](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device lost: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            lost_latch.CountDown();
          },
  });
  adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_EQ(adapter_b_->GetScanMode(),
            BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
  adapter_b_->SetStatus(BluetoothAdapter::Status::kDisabled);
  EXPECT_FALSE(adapter_b_->IsEnabled());
  EXPECT_TRUE(lost_latch.Await(absl::Milliseconds(1000)).result());
}

TEST_F(BluetoothClassicMediumTest, CanStopDiscovery) {
  adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
  CountDownLatch found_latch(1);
  CountDownLatch lost_latch(1);
  bt_a_->StartDiscovery(DiscoveryCallback{
      .device_discovered_cb =
          [this, &found_latch](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            found_latch.CountDown();
          },
      .device_lost_cb =
          [this, &lost_latch](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device lost: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            lost_latch.CountDown();
          },
  });
  adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_EQ(adapter_b_->GetScanMode(),
            BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
  bt_a_->StopDiscovery();
  adapter_b_->SetStatus(BluetoothAdapter::Status::kDisabled);
  EXPECT_FALSE(adapter_b_->IsEnabled());
  EXPECT_FALSE(lost_latch.Await(absl::Milliseconds(1000)).result());
}

TEST_F(BluetoothClassicMediumTest, CanListenForService) {
  adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
  CountDownLatch found_latch(1);
  bt_a_->StartDiscovery(DiscoveryCallback{
      .device_discovered_cb =
          [this, &found_latch](BluetoothDevice& device) {
            NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
            EXPECT_EQ(device.GetName(), adapter_b_->GetName());
            found_latch.CountDown();
          },
  });
  adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_EQ(adapter_b_->GetScanMode(),
            BluetoothAdapter::ScanMode::kConnectableDiscoverable);
  EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
  std::string service_name{"service"};
  std::string service_uuid("service-uuid");
  BluetoothServerSocket server_socket =
      bt_b_->ListenForService(service_name, service_uuid);
  EXPECT_TRUE(server_socket.IsValid());
  server_socket.Close();
}

TEST_F(BluetoothClassicMediumTest, FailIfDiscovering) {
  EXPECT_TRUE(bt_a_->StartDiscovery({}));
  EXPECT_FALSE(bt_a_->StartDiscovery({}));
}

}  // namespace
}  // namespace nearby
}  // namespace location
