/*
 *  Copyright 2021 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 <gmock/gmock.h>
#include <gtest/gtest.h>

#include <condition_variable>
#include <future>
#include <map>
#include <thread>

#include "btif/include/btif_hh.h"
#include "device/include/controller.h"
#include "gd/btaa/activity_attribution.h"
#include "gd/hal/hci_hal.h"
#include "gd/hci/acl_manager_mock.h"
#include "gd/hci/controller_mock.h"
#include "gd/module.h"
#include "gd/os/mock_queue.h"
#include "gd/os/queue.h"
#include "gd/packet/packet_view.h"
#include "hci/acl_manager.h"
#include "hci/acl_manager/classic_acl_connection.h"
#include "hci/acl_manager/connection_callbacks.h"
#include "hci/acl_manager/connection_management_callbacks.h"
#include "hci/acl_manager/le_acl_connection.h"
#include "hci/acl_manager/le_connection_callbacks.h"
#include "hci/acl_manager/le_connection_management_callbacks.h"
#include "hci/include/hci_layer.h"
#include "hci/include/hci_packet_factory.h"
#include "hci/include/hci_packet_parser.h"
#include "include/hardware/bt_activity_attribution.h"
#include "main/shim/acl.h"
#include "main/shim/acl_legacy_interface.h"
#include "main/shim/helpers.h"
#include "os/handler.h"
#include "os/thread.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/bt_hdr.h"
#include "stack/l2cap/l2c_int.h"
#include "test/common/main_handler.h"
#include "test/mock/mock_main_shim_entry.h"
#include "types/raw_address.h"

using namespace bluetooth;
using namespace testing;

namespace test = bluetooth::hci::testing;

const uint8_t kMaxLeAcceptlistSize = 16;
const uint8_t kMaxAddressResolutionSize = kMaxLeAcceptlistSize;

std::map<std::string, int> mock_function_count_map;
tL2C_CB l2cb;
tBTM_CB btm_cb;
btif_hh_cb_t btif_hh_cb;

namespace {
std::map<std::string, std::promise<uint16_t>> mock_function_handle_promise_map;
}

uint8_t mock_get_ble_acceptlist_size() { return 123; }

struct controller_t mock_controller {
  .get_ble_acceptlist_size = mock_get_ble_acceptlist_size,
};

const controller_t* controller_get_interface() { return &mock_controller; }

void mock_on_send_data_upwards(BT_HDR*) { mock_function_count_map[__func__]++; }

void mock_on_packets_completed(uint16_t handle, uint16_t num_packets) {
  mock_function_count_map[__func__]++;
}

void mock_connection_classic_on_connected(const RawAddress& bda,
                                          uint16_t handle, uint8_t enc_mode) {
  mock_function_count_map[__func__]++;
}

void mock_connection_classic_on_failed(const RawAddress& bda,
                                       tHCI_STATUS status) {
  mock_function_count_map[__func__]++;
}

void mock_connection_classic_on_disconnected(tHCI_STATUS status,
                                             uint16_t handle,
                                             tHCI_STATUS reason) {
  mock_function_count_map[__func__]++;
  ASSERT_TRUE(mock_function_handle_promise_map.find(__func__) !=
              mock_function_handle_promise_map.end());
  mock_function_handle_promise_map[__func__].set_value(handle);
}
void mock_connection_le_on_connected(
    const tBLE_BD_ADDR& address_with_type, uint16_t handle, tHCI_ROLE role,
    uint16_t conn_interval, uint16_t conn_latency, uint16_t conn_timeout,
    const RawAddress& local_rpa, const RawAddress& peer_rpa,
    uint8_t peer_addr_type) {
  mock_function_count_map[__func__]++;
}
void mock_connection_le_on_failed(const tBLE_BD_ADDR& address_with_type,
                                  uint16_t handle, bool enhanced,
                                  tHCI_STATUS status) {
  mock_function_count_map[__func__]++;
}
void mock_connection_le_on_disconnected(tHCI_STATUS status, uint16_t handle,
                                        tHCI_STATUS reason) {
  mock_function_count_map[__func__]++;
}

const shim::legacy::acl_interface_t GetMockAclInterface() {
  shim::legacy::acl_interface_t acl_interface{
      .on_send_data_upwards = mock_on_send_data_upwards,
      .on_packets_completed = mock_on_packets_completed,

      .connection.classic.on_connected = mock_connection_classic_on_connected,
      .connection.classic.on_failed = mock_connection_classic_on_failed,
      .connection.classic.on_disconnected =
          mock_connection_classic_on_disconnected,

      .connection.le.on_connected = mock_connection_le_on_connected,
      .connection.le.on_failed = mock_connection_le_on_failed,
      .connection.le.on_disconnected = mock_connection_le_on_disconnected,

      .connection.sco.on_esco_connect_request = nullptr,
      .connection.sco.on_sco_connect_request = nullptr,
      .connection.sco.on_disconnected = nullptr,

      .link.classic.on_authentication_complete = nullptr,
      .link.classic.on_central_link_key_complete = nullptr,
      .link.classic.on_change_connection_link_key_complete = nullptr,
      .link.classic.on_encryption_change = nullptr,
      .link.classic.on_flow_specification_complete = nullptr,
      .link.classic.on_flush_occurred = nullptr,
      .link.classic.on_mode_change = nullptr,
      .link.classic.on_packet_type_changed = nullptr,
      .link.classic.on_qos_setup_complete = nullptr,
      .link.classic.on_read_afh_channel_map_complete = nullptr,
      .link.classic.on_read_automatic_flush_timeout_complete = nullptr,
      .link.classic.on_sniff_subrating = nullptr,
      .link.classic.on_read_clock_complete = nullptr,
      .link.classic.on_read_clock_offset_complete = nullptr,
      .link.classic.on_read_failed_contact_counter_complete = nullptr,
      .link.classic.on_read_link_policy_settings_complete = nullptr,
      .link.classic.on_read_link_quality_complete = nullptr,
      .link.classic.on_read_link_supervision_timeout_complete = nullptr,
      .link.classic.on_read_remote_version_information_complete = nullptr,
      .link.classic.on_read_remote_extended_features_complete = nullptr,
      .link.classic.on_read_rssi_complete = nullptr,
      .link.classic.on_read_transmit_power_level_complete = nullptr,
      .link.classic.on_role_change = nullptr,
      .link.classic.on_role_discovery_complete = nullptr,

      .link.le.on_connection_update = nullptr,
      .link.le.on_data_length_change = nullptr,
      .link.le.on_read_remote_version_information_complete = nullptr,
  };
  return acl_interface;
}

const hci_packet_parser_t* hci_packet_parser_get_interface() { return nullptr; }
const hci_t* hci_layer_get_interface() { return nullptr; }
const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}

template <typename T>
class MockEnQueue : public os::IQueueEnqueue<T> {
  using EnqueueCallback = base::Callback<std::unique_ptr<T>()>;

  void RegisterEnqueue(os::Handler* handler,
                       EnqueueCallback callback) override {}
  void UnregisterEnqueue() override {}
};

template <typename T>
class MockDeQueue : public os::IQueueDequeue<T> {
  using DequeueCallback = base::Callback<void()>;

  void RegisterDequeue(os::Handler* handler,
                       DequeueCallback callback) override {}
  void UnregisterDequeue() override {}
  std::unique_ptr<T> TryDequeue() override { return nullptr; }
};

class MockClassicAclConnection
    : public bluetooth::hci::acl_manager::ClassicAclConnection {
 public:
  MockClassicAclConnection(const hci::Address& address, uint16_t handle) {
    address_ = address;  // ClassicAclConnection
    handle_ = handle;    // AclConnection
  }

  void RegisterCallbacks(
      hci::acl_manager::ConnectionManagementCallbacks* callbacks,
      os::Handler* handler) override {
    callbacks_ = callbacks;
    handler_ = handler;
  }

  // Returns the bidi queue for this mock connection
  AclConnection::QueueUpEnd* GetAclQueueEnd() const override {
    return &mock_acl_queue_;
  }

  mutable common::BidiQueueEnd<hci::BasePacketBuilder,
                               packet::PacketView<hci::kLittleEndian>>
      mock_acl_queue_{&tx_, &rx_};

  MockEnQueue<hci::BasePacketBuilder> tx_;
  MockDeQueue<packet::PacketView<hci::kLittleEndian>> rx_;

  bool ReadRemoteVersionInformation() override { return true; }
  bool ReadRemoteSupportedFeatures() override { return true; }

  bool Disconnect(hci::DisconnectReason reason) override {
    disconnect_cnt_++;
    disconnect_promise_.set_value(handle_);
    return true;
  }

  std::promise<uint16_t> disconnect_promise_;

  hci::acl_manager::ConnectionManagementCallbacks* callbacks_{nullptr};
  os::Handler* handler_{nullptr};

  int disconnect_cnt_{0};
};

namespace bluetooth {
namespace shim {
void init_activity_attribution() {}

namespace testing {
extern os::Handler* mock_handler_;

}  // namespace testing
}  // namespace shim

namespace activity_attribution {
ActivityAttributionInterface* get_activity_attribution_instance() {
  return nullptr;
}

const ModuleFactory ActivityAttribution::Factory =
    ModuleFactory([]() { return nullptr; });
}  // namespace activity_attribution

namespace hal {
const ModuleFactory HciHal::Factory = ModuleFactory([]() { return nullptr; });
}  // namespace hal

}  // namespace bluetooth

class MainShimTest : public testing::Test {
 public:
 protected:
  void SetUp() override {
    main_thread_start_up();

    thread_ = new os::Thread("acl_thread", os::Thread::Priority::NORMAL);
    handler_ = new os::Handler(thread_);

    /* extern */ test::mock_controller_ =
        new bluetooth::hci::testing::MockController();
    /* extern */ test::mock_acl_manager_ =
        new bluetooth::hci::testing::MockAclManager();
  }
  void TearDown() override {
    delete test::mock_controller_;
    test::mock_controller_ = nullptr;
    delete test::mock_acl_manager_;
    test::mock_acl_manager_ = nullptr;

    handler_->Clear();
    delete handler_;
    delete thread_;

    main_thread_shut_down();
  }
  os::Thread* thread_{nullptr};
  os::Handler* handler_{nullptr};

  // Convenience method to create ACL objects
  std::unique_ptr<shim::legacy::Acl> MakeAcl() {
    EXPECT_CALL(*test::mock_acl_manager_, RegisterCallbacks(_, _)).Times(1);
    EXPECT_CALL(*test::mock_acl_manager_, RegisterLeCallbacks(_, _)).Times(1);
    EXPECT_CALL(*test::mock_controller_,
                RegisterCompletedMonitorAclPacketsCallback(_))
        .Times(1);
    EXPECT_CALL(*test::mock_acl_manager_, HACK_SetNonAclDisconnectCallback(_))
        .Times(1);
    EXPECT_CALL(*test::mock_controller_,
                UnregisterCompletedMonitorAclPacketsCallback)
        .Times(1);
    return std::make_unique<shim::legacy::Acl>(handler_, GetMockAclInterface(),
                                               kMaxLeAcceptlistSize,
                                               kMaxAddressResolutionSize);
  }
};

TEST_F(MainShimTest, Nop) {}

TEST_F(MainShimTest, Acl_Lifecycle) {
  auto acl = MakeAcl();
  acl.reset();
  acl = MakeAcl();
}

TEST_F(MainShimTest, helpers) {
  uint8_t reason = 0;
  do {
    hci::ErrorCode gd_error_code = static_cast<hci::ErrorCode>(reason);
    tHCI_STATUS legacy_code = ToLegacyHciErrorCode(gd_error_code);
    ASSERT_EQ(reason,
              static_cast<uint8_t>(ToLegacyHciErrorCode(gd_error_code)));
    ASSERT_EQ(reason, static_cast<uint8_t>(legacy_code));
  } while (++reason != 0);
}

TEST_F(MainShimTest, connect_and_disconnect) {
  hci::Address address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});

  auto acl = MakeAcl();

  // Create connection
  EXPECT_CALL(*test::mock_acl_manager_, CreateConnection(_)).Times(1);
  acl->CreateClassicConnection(address);

  // Respond with a mock connection created
  auto connection = std::make_unique<MockClassicAclConnection>(address, 123);
  ASSERT_EQ(123, connection->GetHandle());
  ASSERT_EQ(hci::Address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}),
            connection->GetAddress());
  MockClassicAclConnection* raw_connection = connection.get();

  acl->OnConnectSuccess(std::move(connection));
  ASSERT_EQ(nullptr, connection);

  // Specify local disconnect request
  auto tx_disconnect_future = raw_connection->disconnect_promise_.get_future();
  acl->DisconnectClassic(123, HCI_SUCCESS);

  // Wait for disconnect to be received
  uint16_t result = tx_disconnect_future.get();
  ASSERT_EQ(123, result);

  // Now emulate the remote disconnect response
  auto handle_promise = std::promise<uint16_t>();
  auto rx_disconnect_future = handle_promise.get_future();
  mock_function_handle_promise_map["mock_connection_classic_on_disconnected"] =
      std::move(handle_promise);
  raw_connection->callbacks_->OnDisconnection(hci::ErrorCode::SUCCESS);

  result = rx_disconnect_future.get();
  ASSERT_EQ(123, result);

  // *Our* task completing indicates reactor is done
  std::promise<void> done;
  auto future = done.get_future();
  handler_->Call([](std::promise<void> done) { done.set_value(); },
                 std::move(done));
  future.wait();
}

TEST_F(MainShimTest, is_flushable) {
  {
    BT_HDR* bt_hdr =
        (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble));

    ASSERT_TRUE(!IsPacketFlushable(bt_hdr));
    HciDataPreamble* hci = ToPacketData<HciDataPreamble>(bt_hdr);
    hci->SetFlushable();
    ASSERT_TRUE(IsPacketFlushable(bt_hdr));

    free(bt_hdr);
  }

  {
    size_t offset = 1024;
    BT_HDR* bt_hdr =
        (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble) + offset);
    bt_hdr->offset = offset;

    ASSERT_TRUE(!IsPacketFlushable(bt_hdr));
    HciDataPreamble* hci = ToPacketData<HciDataPreamble>(bt_hdr);
    hci->SetFlushable();
    ASSERT_TRUE(IsPacketFlushable(bt_hdr));

    free(bt_hdr);
  }

  {
    size_t offset = 1024;
    BT_HDR* bt_hdr =
        (BT_HDR*)calloc(1, sizeof(BT_HDR) + sizeof(HciDataPreamble) + offset);

    uint8_t* p = ToPacketData<uint8_t>(bt_hdr, L2CAP_SEND_CMD_OFFSET);
    UINT16_TO_STREAM(
        p, 0x123 | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT));
    ASSERT_TRUE(!IsPacketFlushable(bt_hdr));

    p = ToPacketData<uint8_t>(bt_hdr, L2CAP_SEND_CMD_OFFSET);
    UINT16_TO_STREAM(p, 0x123 | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
    ASSERT_TRUE(IsPacketFlushable(bt_hdr));

    free(bt_hdr);
  }
}
