/*
 * Copyright 2019 The Android Open Source Project
 *
 * 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
 *
 *      http://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 "neighbor/inquiry.h"

#include <gtest/gtest.h>
#include <unistd.h>

#include <algorithm>
#include <chrono>
#include <future>
#include <map>
#include <memory>

#include "common/bind.h"
#include "common/callback.h"
#include "hci/address.h"
#include "hci/class_of_device.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
#include "os/thread.h"
#include "packet/raw_builder.h"

namespace bluetooth {
namespace neighbor {
namespace {

static const uint8_t kNumberPacketsReadyToReceive = 1;

/**
 * This structure reflects the current state of the bluetooth chip
 * at any given time.
 */
static const int8_t kInitialInquiryResponseTransmitPowerLevel = 123;
static const uint16_t kInitialInquiryScanInterval = 1111;
static const uint16_t kInitialInquiryScanWindow = 2222;

struct HciRegister {
  bool one_shot_inquiry_active;
  bool periodic_inquiry_active;
  int8_t inquiry_response_transmit_power_level;
  uint16_t inquiry_scan_interval;
  uint16_t inquiry_scan_window;
  hci::InquiryScanType inquiry_scan_type;
  hci::InquiryMode inquiry_mode;
  uint8_t inquiry_length;
  uint8_t num_responses;
  uint16_t min_period_length;
  uint16_t max_period_length;
} hci_register_{
    .one_shot_inquiry_active = false,
    .periodic_inquiry_active = false,
    .inquiry_response_transmit_power_level = kInitialInquiryResponseTransmitPowerLevel,
    .inquiry_scan_interval = kInitialInquiryScanInterval,
    .inquiry_scan_window = kInitialInquiryScanWindow,
    .inquiry_scan_type = hci::InquiryScanType::STANDARD,
    .inquiry_mode = hci::InquiryMode::STANDARD,
    .inquiry_length = 0,
    .num_responses = 0,
    .min_period_length = 0,
    .max_period_length = 0,
};

hci::PacketView<hci::kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
  auto bytes = std::make_shared<std::vector<uint8_t>>();
  hci::BitInserter i(*bytes);
  bytes->reserve(packet->size());
  packet->Serialize(i);
  return packet::PacketView<packet::kLittleEndian>(bytes);
}

class TestHciLayer : public hci::HciLayer {
 public:
  void EnqueueCommand(
      std::unique_ptr<hci::CommandBuilder> command,
      common::ContextualOnceCallback<void(hci::CommandCompleteView)> on_complete) override {
    GetHandler()->Post(common::BindOnce(
        &TestHciLayer::HandleCommand, common::Unretained(this), std::move(command), std::move(on_complete)));
  }

  void EnqueueCommand(
      std::unique_ptr<hci::CommandBuilder> command,
      common::ContextualOnceCallback<void(hci::CommandStatusView)> on_status) override {
    GetHandler()->Post(common::BindOnce(
        &TestHciLayer::HandleStatus, common::Unretained(this), std::move(command), std::move(on_status)));
  }

  void HandleCommand(
      std::unique_ptr<hci::CommandBuilder> command_builder,
      common::ContextualOnceCallback<void(hci::CommandCompleteView)> on_complete) {
    hci::CommandView command = hci::CommandView::Create(GetPacketView(std::move(command_builder)));
    ASSERT_TRUE(command.IsValid());

    std::unique_ptr<packet::BasePacketBuilder> event_builder;
    switch (command.GetOpCode()) {
      case hci::OpCode::INQUIRY_CANCEL:
        event_builder =
            hci::InquiryCancelCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        hci_register_.one_shot_inquiry_active = false;
        break;

      case hci::OpCode::PERIODIC_INQUIRY_MODE: {
        auto inquiry = hci::PeriodicInquiryModeView::Create(hci::DiscoveryCommandView::Create(command));
        ASSERT_TRUE(inquiry.IsValid());
        event_builder =
            hci::PeriodicInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        hci_register_.periodic_inquiry_active = true;
        hci_register_.inquiry_length = inquiry.GetInquiryLength();
        hci_register_.num_responses = inquiry.GetNumResponses();
        hci_register_.max_period_length = inquiry.GetMaxPeriodLength();
        hci_register_.min_period_length = inquiry.GetMinPeriodLength();
      } break;

      case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE:
        event_builder =
            hci::ExitPeriodicInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        hci_register_.periodic_inquiry_active = false;
        break;

      case hci::OpCode::WRITE_INQUIRY_MODE:
        event_builder =
            hci::WriteInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        {
          auto view = hci::WriteInquiryModeView::Create(hci::DiscoveryCommandView::Create(command));
          ASSERT_TRUE(view.IsValid());
          hci_register_.inquiry_mode = view.GetInquiryMode();
        }
        break;

      case hci::OpCode::READ_INQUIRY_MODE:
        event_builder = hci::ReadInquiryModeCompleteBuilder::Create(
            kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_mode);
        break;

      case hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY:
        event_builder =
            hci::WriteInquiryScanActivityCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        {
          auto view = hci::WriteInquiryScanActivityView::Create(hci::DiscoveryCommandView::Create(command));
          ASSERT_TRUE(view.IsValid());
          hci_register_.inquiry_scan_interval = view.GetInquiryScanInterval();
          hci_register_.inquiry_scan_window = view.GetInquiryScanWindow();
        }
        break;

      case hci::OpCode::READ_INQUIRY_SCAN_ACTIVITY:
        event_builder = hci::ReadInquiryScanActivityCompleteBuilder::Create(
            kNumberPacketsReadyToReceive,
            hci::ErrorCode::SUCCESS,
            hci_register_.inquiry_scan_interval,
            hci_register_.inquiry_scan_window);
        break;

      case hci::OpCode::WRITE_INQUIRY_SCAN_TYPE:
        event_builder =
            hci::WriteInquiryScanTypeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS);
        {
          auto view = hci::WriteInquiryScanTypeView::Create(hci::DiscoveryCommandView::Create(command));
          ASSERT_TRUE(view.IsValid());
          hci_register_.inquiry_scan_type = view.GetInquiryScanType();
        }
        break;

      case hci::OpCode::READ_INQUIRY_SCAN_TYPE:
        event_builder = hci::ReadInquiryScanTypeCompleteBuilder::Create(
            kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_scan_type);
        break;

      case hci::OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL:
        event_builder = hci::ReadInquiryResponseTransmitPowerLevelCompleteBuilder::Create(
            kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_response_transmit_power_level);
        break;

      default:
        LOG_INFO("Dropping unhandled command:%s", hci::OpCodeText(command.GetOpCode()).c_str());
        return;
    }
    hci::EventView event = hci::EventView::Create(GetPacketView(std::move(event_builder)));
    ASSERT_TRUE(event.IsValid());
    hci::CommandCompleteView command_complete = hci::CommandCompleteView::Create(event);
    ASSERT_TRUE(command_complete.IsValid());
    on_complete.Invoke(std::move(command_complete));

    if (promise_sync_complete_ != nullptr) {
      promise_sync_complete_->set_value(command.GetOpCode());
    }
  }

  void HandleStatus(
      std::unique_ptr<hci::CommandBuilder> command_builder,
      common::ContextualOnceCallback<void(hci::CommandStatusView)> on_status) {
    hci::CommandView command = hci::CommandView::Create(GetPacketView(std::move(command_builder)));
    ASSERT_TRUE(command.IsValid());

    std::unique_ptr<packet::BasePacketBuilder> event_builder;
    switch (command.GetOpCode()) {
      case hci::OpCode::INQUIRY: {
        auto inquiry = hci::InquiryView::Create(hci::DiscoveryCommandView::Create(command));
        ASSERT_TRUE(inquiry.IsValid());
        event_builder = hci::InquiryStatusBuilder::Create(hci::ErrorCode::SUCCESS, kNumberPacketsReadyToReceive);
        hci_register_.one_shot_inquiry_active = true;
        hci_register_.num_responses = inquiry.GetNumResponses();
        hci_register_.inquiry_length = inquiry.GetInquiryLength();
      } break;
      default:
        LOG_INFO("Dropping unhandled status expecting command:%s", hci::OpCodeText(command.GetOpCode()).c_str());
        return;
    }
    hci::EventView event = hci::EventView::Create(GetPacketView(std::move(event_builder)));
    ASSERT_TRUE(event.IsValid());
    hci::CommandStatusView command_status = hci::CommandStatusView::Create(event);
    ASSERT_TRUE(command_status.IsValid());
    on_status.Invoke(std::move(command_status));

    if (promise_sync_complete_ != nullptr) {
      promise_sync_complete_->set_value(command.GetOpCode());
    }
  }

  void RegisterEventHandler(
      hci::EventCode event_code, common::ContextualCallback<void(hci::EventView)> event_handler) override {
    switch (event_code) {
      case hci::EventCode::INQUIRY_RESULT:
        inquiry_result_callback_ = event_handler;
        break;
      case hci::EventCode::INQUIRY_RESULT_WITH_RSSI:
        inquiry_result_with_rssi_callback_ = event_handler;
        break;
      case hci::EventCode::EXTENDED_INQUIRY_RESULT:
        extended_inquiry_result_callback_ = event_handler;
        break;
      case hci::EventCode::INQUIRY_COMPLETE:
        inquiry_complete_callback_ = event_handler;
        break;
      default:
        ASSERT_TRUE(false) << "Unexpected event handler being registered";
        break;
    }
  }

  void UnregisterEventHandler(hci::EventCode event_code) override {
    if (hci_register_.one_shot_inquiry_active || hci_register_.periodic_inquiry_active) {
      LOG_ERROR("Event handlers may not be unregistered until inquiry is stopped");
      return;
    }

    switch (event_code) {
      case hci::EventCode::INQUIRY_RESULT:
        inquiry_result_callback_ = {};
        break;
      case hci::EventCode::INQUIRY_RESULT_WITH_RSSI:
        inquiry_result_with_rssi_callback_ = {};
        break;
      case hci::EventCode::EXTENDED_INQUIRY_RESULT:
        extended_inquiry_result_callback_ = {};
        break;
      case hci::EventCode::INQUIRY_COMPLETE:
        inquiry_complete_callback_ = {};
        break;
      default:
        ASSERT_TRUE(false) << "Unexpected event handler being unregistered";
        break;
    }
  }

  void Synchronize(std::function<void()> func, hci::OpCode op_code) {
    ASSERT_EQ(promise_sync_complete_, nullptr);
    promise_sync_complete_ = new std::promise<hci::OpCode>();
    auto future = promise_sync_complete_->get_future();
    func();
    auto result = future.wait_for(std::chrono::milliseconds(100));
    ASSERT_EQ(std::future_status::ready, result);
    ASSERT_EQ(op_code, future.get());
    delete promise_sync_complete_;
    promise_sync_complete_ = nullptr;
  }

  void InjectInquiryResult(std::unique_ptr<hci::InquiryResultBuilder> result) {
    hci::EventView view = hci::EventView::Create(GetPacketView(std::move(result)));
    ASSERT_TRUE(view.IsValid());
    inquiry_result_callback_.Invoke(std::move(view));
  }

  void ListDependencies(ModuleList* list) const {}
  void Start() override {}
  void Stop() override {}

 private:
  std::promise<hci::OpCode>* promise_sync_complete_{nullptr};

  common::ContextualCallback<void(hci::EventView)> inquiry_result_callback_;
  common::ContextualCallback<void(hci::EventView)> inquiry_result_with_rssi_callback_;
  common::ContextualCallback<void(hci::EventView)> extended_inquiry_result_callback_;
  common::ContextualCallback<void(hci::EventView)> inquiry_complete_callback_;
};

class InquiryTest : public ::testing::Test {
 public:
  void Result(hci::InquiryResultView view) {
    ASSERT_TRUE(view.size() >= sizeof(uint16_t));
    promise_result_complete_->set_value(true);
  }

  void WaitForInquiryResult(std::function<void()> func) {
    ASSERT_EQ(promise_result_complete_, nullptr);
    promise_result_complete_ = new std::promise<bool>();
    auto future = promise_result_complete_->get_future();
    func();
    future.wait();
    delete promise_result_complete_;
    promise_result_complete_ = nullptr;
  }

  void ResultWithRssi(hci::InquiryResultWithRssiView view) {
    ASSERT_TRUE(view.size() >= sizeof(uint16_t));
  }

  void ExtendedResult(hci::ExtendedInquiryResultView view) {
    ASSERT_TRUE(view.size() >= sizeof(uint16_t));
  }

  void Complete(hci::ErrorCode status) {}

 protected:
  void SetUp() override {
    test_hci_layer_ = new TestHciLayer;
    fake_registry_.InjectTestModule(&hci::HciLayer::Factory, test_hci_layer_);
    client_handler_ = fake_registry_.GetTestModuleHandler(&hci::HciLayer::Factory);
    fake_registry_.Start<InquiryModule>(&thread_);

    inquiry_module_ = static_cast<InquiryModule*>(fake_registry_.GetModuleUnderTest(&InquiryModule::Factory));

    InquiryCallbacks inquiry_callbacks;
    inquiry_callbacks.result = std::bind(&InquiryTest::Result, this, std::placeholders::_1);
    inquiry_callbacks.result_with_rssi = std::bind(&InquiryTest::ResultWithRssi, this, std::placeholders::_1);
    inquiry_callbacks.extended_result = std::bind(&InquiryTest::ExtendedResult, this, std::placeholders::_1);
    inquiry_callbacks.complete = std::bind(&InquiryTest::Complete, this, std::placeholders::_1);
    inquiry_module_->RegisterCallbacks(inquiry_callbacks);
  }

  void TearDown() override {
    inquiry_module_->UnregisterCallbacks();
    fake_registry_.StopAll();
  }

  TestModuleRegistry fake_registry_;
  TestHciLayer* test_hci_layer_ = nullptr;
  os::Thread& thread_ = fake_registry_.GetTestThread();
  InquiryModule* inquiry_module_ = nullptr;
  os::Handler* client_handler_ = nullptr;

  std::promise<bool>* promise_result_complete_{nullptr};
};

TEST_F(InquiryTest, Module) {}

TEST_F(InquiryTest, SetInquiryModes) {
  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->SetInquiryWithRssiResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE);
  ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::RSSI);

  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->SetExtendedInquiryResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE);
  ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::RSSI_OR_EXTENDED);

  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->SetStandardInquiryResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE);
  ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::STANDARD);
}

TEST_F(InquiryTest, SetScanType) {
  test_hci_layer_->Synchronize([this] { inquiry_module_->SetInterlacedScan(); }, hci::OpCode::WRITE_INQUIRY_SCAN_TYPE);
  ASSERT_EQ(hci_register_.inquiry_scan_type, hci::InquiryScanType::INTERLACED);

  test_hci_layer_->Synchronize([this] { inquiry_module_->SetStandardScan(); }, hci::OpCode::WRITE_INQUIRY_SCAN_TYPE);
  ASSERT_EQ(hci_register_.inquiry_scan_type, hci::InquiryScanType::STANDARD);
}

TEST_F(InquiryTest, ScanActivity) {
  ScanParameters params{
      .interval = 0x1234,
      .window = 0x5678,
  };

  test_hci_layer_->Synchronize(
      [this, params] { inquiry_module_->SetScanActivity(params); }, hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY);
  ASSERT_EQ(params.interval, hci_register_.inquiry_scan_interval);
  ASSERT_EQ(params.window, hci_register_.inquiry_scan_window);
}

TEST_F(InquiryTest, OneShotGeneralInquiry) {
  uint8_t inquiry_length = 128;
  uint8_t num_responses = 100;
  test_hci_layer_->Synchronize(
      [this, inquiry_length, num_responses] { inquiry_module_->StartGeneralInquiry(inquiry_length, num_responses); },
      hci::OpCode::INQUIRY);
  ASSERT_EQ(inquiry_length, hci_register_.inquiry_length);
  ASSERT_EQ(num_responses, hci_register_.num_responses);

  test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL);
}

TEST_F(InquiryTest, OneShotLimitedInquiry) {
  test_hci_layer_->Synchronize([this] { inquiry_module_->StartLimitedInquiry(128, 100); }, hci::OpCode::INQUIRY);

  test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL);
}

TEST_F(InquiryTest, GeneralPeriodicInquiry) {
  uint8_t inquiry_length = 128;
  uint8_t num_responses = 100;
  uint16_t max_delay = 1100;
  uint16_t min_delay = 200;
  test_hci_layer_->Synchronize(
      [this, inquiry_length, num_responses, max_delay, min_delay] {
        inquiry_module_->StartGeneralPeriodicInquiry(inquiry_length, num_responses, max_delay, min_delay);
      },
      hci::OpCode::PERIODIC_INQUIRY_MODE);
  ASSERT_EQ(inquiry_length, hci_register_.inquiry_length);
  ASSERT_EQ(num_responses, hci_register_.num_responses);
  ASSERT_EQ(max_delay, hci_register_.max_period_length);
  ASSERT_EQ(min_delay, hci_register_.min_period_length);

  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->StopPeriodicInquiry(); }, hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE);
}

TEST_F(InquiryTest, LimitedPeriodicInquiry) {
  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->StartLimitedPeriodicInquiry(128, 100, 1100, 200); },
      hci::OpCode::PERIODIC_INQUIRY_MODE);

  test_hci_layer_->Synchronize(
      [this] { inquiry_module_->StopPeriodicInquiry(); }, hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE);
}

TEST_F(InquiryTest, InjectInquiryResult) {
  test_hci_layer_->Synchronize([this] { inquiry_module_->StartGeneralInquiry(128, 100); }, hci::OpCode::INQUIRY);

  WaitForInquiryResult([this] {
    const std::vector<hci::InquiryResult> inquiry_results;
    auto packet = hci::InquiryResultBuilder::Create(inquiry_results);
    test_hci_layer_->InjectInquiryResult(std::move(packet));
  });
  test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL);
}

}  // namespace
}  // namespace neighbor
}  // namespace bluetooth
