/*
 * 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 "hci/controller.h"

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

#include <gtest/gtest.h>

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

namespace bluetooth {
namespace hci {
namespace {

using common::BidiQueue;
using common::BidiQueueEnd;
using packet::kLittleEndian;
using packet::PacketView;
using packet::RawBuilder;

constexpr uint16_t kHandle1 = 0x123;
constexpr uint16_t kCredits1 = 0x78;
constexpr uint16_t kHandle2 = 0x456;
constexpr uint16_t kCredits2 = 0x9a;
uint16_t feature_spec_version = 55;

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

class TestHciLayer : public HciLayer {
 public:
  void EnqueueCommand(
      std::unique_ptr<CommandBuilder> command,
      common::ContextualOnceCallback<void(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<CommandBuilder> command,
      common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
    EXPECT_TRUE(false) << "Controller properties should not generate Command Status";
  }

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

    uint8_t num_packets = 1;
    std::unique_ptr<packet::BasePacketBuilder> event_builder;
    switch (command.GetOpCode()) {
      case (OpCode::READ_LOCAL_NAME): {
        std::array<uint8_t, 248> local_name = {'D', 'U', 'T', '\0'};
        event_builder = ReadLocalNameCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, local_name);
      } break;
      case (OpCode::READ_LOCAL_VERSION_INFORMATION): {
        LocalVersionInformation local_version_information;
        local_version_information.hci_version_ = HciVersion::V_5_0;
        local_version_information.hci_revision_ = 0x1234;
        local_version_information.lmp_version_ = LmpVersion::V_4_2;
        local_version_information.manufacturer_name_ = 0xBAD;
        local_version_information.lmp_subversion_ = 0x5678;
        event_builder = ReadLocalVersionInformationCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS,
                                                                           local_version_information);
      } break;
      case (OpCode::READ_LOCAL_SUPPORTED_COMMANDS): {
        std::array<uint8_t, 64> supported_commands;
        for (int i = 0; i < 37; i++) {
          supported_commands[i] = 0xff;
        }
        for (int i = 37; i < 64; i++) {
          supported_commands[i] = 0x00;
        }
        event_builder =
            ReadLocalSupportedCommandsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, supported_commands);
      } break;
      case (OpCode::READ_LOCAL_EXTENDED_FEATURES): {
        ReadLocalExtendedFeaturesView read_command = ReadLocalExtendedFeaturesView::Create(command);
        ASSERT_TRUE(read_command.IsValid());
        uint8_t page_bumber = read_command.GetPageNumber();
        uint64_t lmp_features = 0x012345678abcdef;
        lmp_features += page_bumber;
        event_builder = ReadLocalExtendedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, page_bumber,
                                                                         0x02, lmp_features);
      } break;
      case (OpCode::READ_BUFFER_SIZE): {
        event_builder = ReadBufferSizeCompleteBuilder::Create(
            num_packets, ErrorCode::SUCCESS, acl_data_packet_length, synchronous_data_packet_length,
            total_num_acl_data_packets, total_num_synchronous_data_packets);
      } break;
      case (OpCode::READ_BD_ADDR): {
        event_builder = ReadBdAddrCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, Address::kAny);
      } break;
      case (OpCode::LE_READ_BUFFER_SIZE_V1): {
        LeBufferSize le_buffer_size;
        le_buffer_size.le_data_packet_length_ = 0x16;
        le_buffer_size.total_num_le_packets_ = 0x08;
        event_builder = LeReadBufferSizeV1CompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_buffer_size);
      } break;
      case (OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES): {
        event_builder =
            LeReadLocalSupportedFeaturesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abc);
      } break;
      case (OpCode::LE_READ_SUPPORTED_STATES): {
        event_builder =
            LeReadSupportedStatesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x001f123456789abe);
      } break;
      case (OpCode::LE_READ_MAXIMUM_DATA_LENGTH): {
        LeMaximumDataLength le_maximum_data_length;
        le_maximum_data_length.supported_max_tx_octets_ = 0x12;
        le_maximum_data_length.supported_max_tx_time_ = 0x34;
        le_maximum_data_length.supported_max_rx_octets_ = 0x56;
        le_maximum_data_length.supported_max_rx_time_ = 0x78;
        event_builder =
            LeReadMaximumDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, le_maximum_data_length);
      } break;
      case (OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH): {
        event_builder =
            LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0x0672);
      } break;
      case (OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS): {
        event_builder =
            LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0xF0);
      } break;
      case (OpCode::LE_GET_VENDOR_CAPABILITIES): {
        BaseVendorCapabilities base_vendor_capabilities;
        base_vendor_capabilities.max_advt_instances_ = 0x10;
        base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01;
        base_vendor_capabilities.total_scan_results_storage_ = 0x2800;
        base_vendor_capabilities.max_irk_list_sz_ = 0x20;
        base_vendor_capabilities.filtering_support_ = 0x01;
        base_vendor_capabilities.max_filter_ = 0x10;
        base_vendor_capabilities.activity_energy_info_support_ = 0x01;

        auto payload = std::make_unique<RawBuilder>();
        if (feature_spec_version > 55) {
          std::vector<uint8_t> payload_bytes = {0x20, 0x00, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00};
          payload->AddOctets2(feature_spec_version);
          payload->AddOctets(payload_bytes);
        }
        event_builder = LeGetVendorCapabilitiesCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS,
                                                                       base_vendor_capabilities, std::move(payload));
      } break;
      case (OpCode::SET_EVENT_MASK): {
        auto view = SetEventMaskView::Create(command);
        ASSERT_TRUE(view.IsValid());
        event_mask = view.GetEventMask();
        event_builder = SetEventMaskCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS);
      } break;
      case (OpCode::LE_SET_EVENT_MASK): {
        auto view = LeSetEventMaskView::Create(command);
        ASSERT_TRUE(view.IsValid());
        le_event_mask = view.GetLeEventMask();
        event_builder = LeSetEventMaskCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS);
      } break;

      case (OpCode::RESET):
      case (OpCode::SET_EVENT_FILTER):
      case (OpCode::HOST_BUFFER_SIZE):
        command_queue_.push(command);
        not_empty_.notify_all();
        return;
      default:
        LOG_INFO("Dropping unhandled packet");
        return;
    }
    auto packet = GetPacketView(std::move(event_builder));
    EventView event = EventView::Create(packet);
    ASSERT_TRUE(event.IsValid());
    CommandCompleteView command_complete = CommandCompleteView::Create(event);
    ASSERT_TRUE(command_complete.IsValid());
    on_complete.Invoke(std::move(command_complete));
  }

  void RegisterEventHandler(EventCode event_code, common::ContextualCallback<void(EventView)> event_handler) override {
    EXPECT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed";
    number_of_completed_packets_callback_ = event_handler;
  }

  void UnregisterEventHandler(EventCode event_code) override {
    EXPECT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed";
    number_of_completed_packets_callback_ = {};
  }

  void IncomingCredit() {
    std::vector<CompletedPackets> completed_packets;
    CompletedPackets cp;
    cp.host_num_of_completed_packets_ = kCredits1;
    cp.connection_handle_ = kHandle1;
    completed_packets.push_back(cp);
    cp.host_num_of_completed_packets_ = kCredits2;
    cp.connection_handle_ = kHandle2;
    completed_packets.push_back(cp);
    auto event_builder = NumberOfCompletedPacketsBuilder::Create(completed_packets);
    auto packet = GetPacketView(std::move(event_builder));
    EventView event = EventView::Create(packet);
    ASSERT_TRUE(event.IsValid());
    number_of_completed_packets_callback_.Invoke(event);
  }

  CommandView GetCommand(OpCode op_code) {
    std::unique_lock<std::mutex> lock(mutex_);
    std::chrono::milliseconds time = std::chrono::milliseconds(3000);

    // wait for command
    while (command_queue_.size() == 0) {
      if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) {
        break;
      }
    }
    EXPECT_TRUE(command_queue_.size() > 0);
    if (command_queue_.empty()) {
      return CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
    }
    CommandView command = command_queue_.front();
    EXPECT_EQ(command.GetOpCode(), op_code);
    command_queue_.pop();
    return command;
  }

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

  constexpr static uint16_t acl_data_packet_length = 1024;
  constexpr static uint8_t synchronous_data_packet_length = 60;
  constexpr static uint16_t total_num_acl_data_packets = 10;
  constexpr static uint16_t total_num_synchronous_data_packets = 12;
  uint64_t event_mask = 0;
  uint64_t le_event_mask = 0;

 private:
  common::ContextualCallback<void(EventView)> number_of_completed_packets_callback_;
  std::queue<CommandView> command_queue_;
  mutable std::mutex mutex_;
  std::condition_variable not_empty_;
};

class ControllerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    bluetooth::common::InitFlags::SetAllForTesting();
    test_hci_layer_ = new TestHciLayer;
    fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
    client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
    fake_registry_.Start<Controller>(&thread_);
    controller_ = static_cast<Controller*>(fake_registry_.GetModuleUnderTest(&Controller::Factory));
  }

  void TearDown() override {
    fake_registry_.StopAll();
  }

  TestModuleRegistry fake_registry_;
  TestHciLayer* test_hci_layer_ = nullptr;
  os::Thread& thread_ = fake_registry_.GetTestThread();
  Controller* controller_ = nullptr;
  os::Handler* client_handler_ = nullptr;
};

TEST_F(ControllerTest, startup_teardown) {}

TEST_F(ControllerTest, read_controller_info) {
  ASSERT_EQ(controller_->GetAclPacketLength(), test_hci_layer_->acl_data_packet_length);
  ASSERT_EQ(controller_->GetNumAclPacketBuffers(), test_hci_layer_->total_num_acl_data_packets);
  ASSERT_EQ(controller_->GetScoPacketLength(), test_hci_layer_->synchronous_data_packet_length);
  ASSERT_EQ(controller_->GetNumScoPacketBuffers(), test_hci_layer_->total_num_synchronous_data_packets);
  ASSERT_EQ(controller_->GetMacAddress(), Address::kAny);
  LocalVersionInformation local_version_information = controller_->GetLocalVersionInformation();
  ASSERT_EQ(local_version_information.hci_version_, HciVersion::V_5_0);
  ASSERT_EQ(local_version_information.hci_revision_, 0x1234);
  ASSERT_EQ(local_version_information.lmp_version_, LmpVersion::V_4_2);
  ASSERT_EQ(local_version_information.manufacturer_name_, 0xBAD);
  ASSERT_EQ(local_version_information.lmp_subversion_, 0x5678);
  ASSERT_EQ(controller_->GetLeBufferSize().le_data_packet_length_, 0x16);
  ASSERT_EQ(controller_->GetLeBufferSize().total_num_le_packets_, 0x08);
  ASSERT_EQ(controller_->GetLeSupportedStates(), 0x001f123456789abe);
  ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_tx_octets_, 0x12);
  ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_tx_time_, 0x34);
  ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_rx_octets_, 0x56);
  ASSERT_EQ(controller_->GetLeMaximumDataLength().supported_max_rx_time_, 0x78);
  ASSERT_EQ(controller_->GetLeMaximumAdvertisingDataLength(), 0x0672);
  ASSERT_EQ(controller_->GetLeNumberOfSupportedAdverisingSets(), 0xF0);
}

TEST_F(ControllerTest, read_write_local_name) {
  ASSERT_EQ(controller_->GetLocalName(), "DUT");
  controller_->WriteLocalName("New name");
  ASSERT_EQ(controller_->GetLocalName(), "New name");
}

TEST_F(ControllerTest, send_set_event_mask_command) {
  uint64_t new_event_mask = test_hci_layer_->event_mask - 1;
  controller_->SetEventMask(new_event_mask);
  // Send another command to make sure it was applied
  controller_->Reset();
  auto packet = test_hci_layer_->GetCommand(OpCode::RESET);
  ASSERT_EQ(new_event_mask, test_hci_layer_->event_mask);
}

TEST_F(ControllerTest, send_reset_command) {
  controller_->Reset();
  auto packet = test_hci_layer_->GetCommand(OpCode::RESET);
  auto command = ResetView::Create(packet);
  ASSERT_TRUE(command.IsValid());
}

TEST_F(ControllerTest, send_set_event_filter_command) {
  controller_->SetEventFilterInquiryResultAllDevices();
  auto packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view1 = SetEventFilterView::Create(packet);
  auto set_event_filter_inquiry_result_view1 = SetEventFilterInquiryResultView::Create(set_event_filter_view1);
  auto command1 = SetEventFilterInquiryResultAllDevicesView::Create(set_event_filter_inquiry_result_view1);
  ASSERT_TRUE(command1.IsValid());

  ClassOfDevice class_of_device({0xab, 0xcd, 0xef});
  ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56});
  controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask);
  packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view2 = SetEventFilterView::Create(packet);
  auto set_event_filter_inquiry_result_view2 = SetEventFilterInquiryResultView::Create(set_event_filter_view2);
  auto command2 = SetEventFilterInquiryResultClassOfDeviceView::Create(set_event_filter_inquiry_result_view2);
  ASSERT_TRUE(command2.IsValid());
  ASSERT_EQ(command2.GetClassOfDevice(), class_of_device);

  Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
  controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED);
  packet = test_hci_layer_->GetCommand(OpCode::SET_EVENT_FILTER);
  auto set_event_filter_view3 = SetEventFilterView::Create(packet);
  auto set_event_filter_connection_setup_view = SetEventFilterConnectionSetupView::Create(set_event_filter_view3);
  auto command3 = SetEventFilterConnectionSetupAddressView::Create(set_event_filter_connection_setup_view);
  ASSERT_TRUE(command3.IsValid());
  ASSERT_EQ(command3.GetAddress(), bdaddr);
}

TEST_F(ControllerTest, send_host_buffer_size_command) {
  controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03);
  auto packet = test_hci_layer_->GetCommand(OpCode::HOST_BUFFER_SIZE);
  auto command = HostBufferSizeView::Create(packet);
  ASSERT_TRUE(command.IsValid());
  ASSERT_EQ(command.GetHostAclDataPacketLength(), 0xFF00);
  ASSERT_EQ(command.GetHostSynchronousDataPacketLength(), 0xF1);
  ASSERT_EQ(command.GetHostTotalNumAclDataPackets(), 0xFF02);
  ASSERT_EQ(command.GetHostTotalNumSynchronousDataPackets(), 0xFF03);
}

TEST_F(ControllerTest, send_le_set_event_mask_command) {
  uint64_t new_le_event_mask = test_hci_layer_->event_mask - 1;
  controller_->LeSetEventMask(new_le_event_mask);
  // Send another command to make sure it was applied
  controller_->Reset();
  auto packet = test_hci_layer_->GetCommand(OpCode::RESET);
  ASSERT_EQ(new_le_event_mask, test_hci_layer_->le_event_mask);
}

TEST_F(ControllerTest, is_supported_test) {
  ASSERT_TRUE(controller_->IsSupported(OpCode::INQUIRY));
  ASSERT_TRUE(controller_->IsSupported(OpCode::REJECT_CONNECTION_REQUEST));
  ASSERT_TRUE(controller_->IsSupported(OpCode::ACCEPT_CONNECTION_REQUEST));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_REMOVE_ADVERTISING_SET));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_CLEAR_ADVERTISING_SETS));
  ASSERT_FALSE(controller_->IsSupported(OpCode::LE_SET_PERIODIC_ADVERTISING_PARAM));
}

TEST_F(ControllerTest, feature_spec_version_055_test) {
  EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 55);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 95;
}

TEST_F(ControllerTest, feature_spec_version_095_test) {
  EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 95);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 96;
}

TEST_F(ControllerTest, feature_spec_version_096_test) {
  EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 96);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
  feature_spec_version = 98;
}

TEST_F(ControllerTest, feature_spec_version_098_test) {
  EXPECT_EQ(controller_->GetVendorCapabilities().version_supported_, 98);
  EXPECT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT));
  EXPECT_FALSE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO));
  EXPECT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE));
}

std::promise<void> credits1_set;
std::promise<void> credits2_set;

void CheckReceivedCredits(uint16_t handle, uint16_t credits) {
  switch (handle) {
    case (kHandle1):
      ASSERT_EQ(kCredits1, credits);
      credits1_set.set_value();
      break;
    case (kHandle2):
      ASSERT_EQ(kCredits2, credits);
      credits2_set.set_value();
      break;
    default:
      ASSERT_LOG(false, "Unknown handle 0x%0hx with 0x%0hx credits", handle, credits);
  }
}

TEST_F(ControllerTest, aclCreditCallbacksTest) {
  controller_->RegisterCompletedAclPacketsCallback(client_handler_->Bind(&CheckReceivedCredits));

  test_hci_layer_->IncomingCredit();

  credits1_set.get_future().wait();
  credits2_set.get_future().wait();
}

TEST_F(ControllerTest, aclCreditCallbackListenerUnregistered) {
  os::Thread thread("test_thread", os::Thread::Priority::NORMAL);
  os::Handler handler(&thread);
  controller_->RegisterCompletedAclPacketsCallback(handler.Bind(&CheckReceivedCredits));

  handler.Clear();
  handler.WaitUntilStopped(std::chrono::milliseconds(100));
  controller_->UnregisterCompletedAclPacketsCallback();

  test_hci_layer_->IncomingCredit();
}
}  // namespace
}  // namespace hci
}  // namespace bluetooth
