// Copyright 2020 The Fuchsia 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 "command_handler.h"

#include <gtest/gtest.h>

#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/mock_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_packets.h"

namespace bt::hci {

namespace {

constexpr OpCode kOpCode(kInquiry);
constexpr uint8_t kTestEventParam = 3u;

template <bool DecodeSucceeds>
struct TestEvent {
  uint8_t test_param;
  static fit::result<TestEvent, HostError> Decode(const EventPacket& packet) {
    if (!DecodeSucceeds) {
      return fit::error(HostError::kPacketMalformed);
    }

    return fit::ok(TestEvent{.test_param = kTestEventParam});
  }

  static constexpr EventCode kEventCode = kInquiryCompleteEventCode;
};
using DecodableEvent = TestEvent<true>;
using UndecodableEvent = TestEvent<false>;

DynamicByteBuffer MakeTestEventPacket(StatusCode status = StatusCode::kSuccess) {
  return DynamicByteBuffer(StaticByteBuffer(DecodableEvent::kEventCode,
                                            0x01,  // parameters_total_size
                                            status));
}

template <bool DecodeSucceeds>
struct TestCommandCompleteEvent {
  uint8_t test_param;

  static fit::result<TestCommandCompleteEvent, HostError> Decode(const EventPacket& packet) {
    if (!DecodeSucceeds) {
      return fit::error(HostError::kPacketMalformed);
    }

    return fit::ok(TestCommandCompleteEvent{.test_param = kTestEventParam});
  }

  static constexpr EventCode kEventCode = kCommandCompleteEventCode;
};
using DecodableCommandCompleteEvent = TestCommandCompleteEvent<true>;
using UndecodableCommandCompleteEvent = TestCommandCompleteEvent<false>;

constexpr uint8_t kEncodedTestCommandParam = 2u;

template <typename CompleteEventT>
struct TestCommand {
  uint8_t test_param;

  std::unique_ptr<CommandPacket> Encode() {
    auto packet = CommandPacket::New(kOpCode, sizeof(test_param));
    auto* payload = packet->mutable_payload<decltype(test_param)>();
    *payload = kEncodedTestCommandParam;
    return packet;
  }

  static OpCode opcode() { return kOpCode; }

  using EventT = CompleteEventT;
};

const TestCommand<DecodableEvent> kTestCommandWithAsyncEvent{.test_param = 1u};
const TestCommand<DecodableCommandCompleteEvent> kTestCommandWithCommandCompleteEvent{.test_param =
                                                                                          1u};
const TestCommand<UndecodableCommandCompleteEvent> kTestCommandWithUndecodableCommandCompleteEvent{
    .test_param = 1u};

const auto kTestCommandPacket = StaticByteBuffer(LowerBits(kOpCode), UpperBits(kOpCode),
                                                 0x01,  // param length
                                                 kEncodedTestCommandParam);

using TestingBase = bt::testing::ControllerTest<bt::testing::MockController>;
class HCI_CommandHandlerTest : public TestingBase {
 public:
  void SetUp() override {
    TestingBase::SetUp();
    StartTestDevice();
    handler_.emplace(cmd_channel()->AsWeakPtr());
  }

  CommandHandler& handler() { return handler_.value(); }

 private:
  std::optional<CommandHandler> handler_;
};

TEST_F(HCI_CommandHandlerTest, SuccessfulSendCommandWithSyncEvent) {
  const auto kEventPacket = testing::CommandCompletePacket(kOpCode, StatusCode::kSuccess);
  EXPECT_CMD_PACKET_OUT(test_device(), kTestCommandPacket, &kEventPacket);

  std::optional<DecodableCommandCompleteEvent> event;
  handler().SendCommand(kTestCommandWithCommandCompleteEvent, [&event](auto result) {
    ASSERT_TRUE(result.is_ok());
    event = result.value();
  });

  RunLoopUntilIdle();
  ASSERT_TRUE(event.has_value());
  EXPECT_EQ(event->test_param, kTestEventParam);
}

TEST_F(HCI_CommandHandlerTest, SendCommandReceiveFailEvent) {
  const auto kEventPacket = testing::CommandCompletePacket(kOpCode, StatusCode::kCommandDisallowed);
  EXPECT_CMD_PACKET_OUT(test_device(), kTestCommandPacket, &kEventPacket);

  std::optional<Status> status;
  handler().SendCommand(kTestCommandWithCommandCompleteEvent, [&status](auto result) {
    ASSERT_TRUE(result.is_error());
    status = result.error();
  });

  RunLoopUntilIdle();
  ASSERT_TRUE(status.has_value());
  EXPECT_EQ(status.value(), Status(StatusCode::kCommandDisallowed));
}

TEST_F(HCI_CommandHandlerTest, SendCommandWithSyncEventFailsToDecode) {
  const auto kEventPacket = testing::CommandCompletePacket(kOpCode, StatusCode::kSuccess);
  EXPECT_CMD_PACKET_OUT(test_device(), kTestCommandPacket, &kEventPacket);

  std::optional<Status> status;
  handler().SendCommand(kTestCommandWithUndecodableCommandCompleteEvent, [&status](auto result) {
    ASSERT_TRUE(result.is_error());
    status = result.error();
  });

  RunLoopUntilIdle();
  ASSERT_TRUE(status.has_value());
  EXPECT_EQ(status.value(), Status(HostError::kPacketMalformed));
}

TEST_F(HCI_CommandHandlerTest, SuccessfulSendCommandWithAsyncEvent) {
  const auto kTestEventPacket = MakeTestEventPacket();
  const auto kStatusEventPacket = testing::CommandStatusPacket(kOpCode, StatusCode::kSuccess);
  EXPECT_CMD_PACKET_OUT(test_device(), kTestCommandPacket, &kStatusEventPacket, &kTestEventPacket);

  std::optional<DecodableEvent> event;
  size_t cb_count = 0;
  handler().SendCommand(kTestCommandWithAsyncEvent, [&event, &cb_count](auto result) {
    ASSERT_TRUE(result.is_ok());
    event = result.value();
    cb_count++;
  });

  RunLoopUntilIdle();
  ASSERT_EQ(cb_count, 1u);
  ASSERT_TRUE(event.has_value());
  EXPECT_EQ(event->test_param, kTestEventParam);
}

TEST_F(HCI_CommandHandlerTest, AddEventHandlerSuccess) {
  std::optional<DecodableEvent> event;
  size_t cb_count = 0;
  handler().AddEventHandler<DecodableEvent>([&event, &cb_count](auto cb_event) {
    cb_count++;
    event = cb_event;
    return CommandChannel::EventCallbackResult::kContinue;
  });
  test_device()->SendCommandChannelPacket(MakeTestEventPacket());
  test_device()->SendCommandChannelPacket(MakeTestEventPacket());
  RunLoopUntilIdle();
  EXPECT_EQ(cb_count, 2u);
  ASSERT_TRUE(event.has_value());
  EXPECT_EQ(event->test_param, kTestEventParam);
}

TEST_F(HCI_CommandHandlerTest, AddEventHandlerDecodeError) {
  size_t cb_count = 0;
  handler().AddEventHandler<UndecodableEvent>([&cb_count](auto cb_event) {
    cb_count++;
    return CommandChannel::EventCallbackResult::kContinue;
  });
  test_device()->SendCommandChannelPacket(MakeTestEventPacket());
  test_device()->SendCommandChannelPacket(MakeTestEventPacket());
  RunLoopUntilIdle();
  EXPECT_EQ(cb_count, 0u);
}

TEST_F(HCI_CommandHandlerTest, SendCommandFinishOnStatus) {
  const auto kStatusEventPacket = testing::CommandStatusPacket(kOpCode, StatusCode::kSuccess);
  EXPECT_CMD_PACKET_OUT(test_device(), kTestCommandPacket, &kStatusEventPacket);

  size_t cb_count = 0;
  handler().SendCommandFinishOnStatus(kTestCommandWithAsyncEvent, [&cb_count](auto result) {
    ASSERT_TRUE(result.is_ok());
    cb_count++;
  });

  RunLoopUntilIdle();
  ASSERT_EQ(cb_count, 1u);
}

}  // namespace
}  // namespace bt::hci
