// Copyright 2017 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 "src/connectivity/bluetooth/core/bt-host/hci/sequential_command_runner.h"

#include "src/connectivity/bluetooth/core/bt-host/common/log.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_controller.h"

namespace bt {
namespace hci {
namespace {

constexpr OpCode kTestOpCode = 0xFFFF;
constexpr OpCode kTestOpCode2 = 0xF00F;

using bt::testing::CommandTransaction;

using TestingBase = bt::testing::FakeControllerTest<bt::testing::TestController>;

class SequentialCommandRunnerTest : public TestingBase {
 public:
  SequentialCommandRunnerTest() = default;
  ~SequentialCommandRunnerTest() override = default;
};

using HCI_SequentialCommandRunnerTest = SequentialCommandRunnerTest;

TEST_F(HCI_SequentialCommandRunnerTest, SequentialCommandRunner) {
  // HCI command with custom opcode FFFF.
  auto command_bytes = CreateStaticByteBuffer(0xFF, 0xFF, 0x00);

  auto command_status_error_bytes =
      CreateStaticByteBuffer(kCommandStatusEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             StatusCode::kHardwareFailure, 1, 0xFF, 0xFF);

  auto command_cmpl_error_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             1, 0xFF, 0xFF, StatusCode::kReserved0);

  auto command_cmpl_success_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             1, 0xFF, 0xFF, StatusCode::kSuccess);

  // Here we perform multiple test sequences where we queue up several  commands
  // in each sequence. We expect each sequence to terminate differently after
  // the following HCI transactions:
  //
  // Sequence 1 (HCI packets)
  //    -> Command; <- error status
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_status_error_bytes}));

  // Sequence 2 (HCI packets)
  //    -> Command; <- error complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_error_bytes}));

  // Sequence 3 (HCI packets)
  //    -> Command; <- success complete
  //    -> Command; <- error complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_error_bytes}));

  // Sequence 4 (HCI packets)
  //    -> Command; <- success complete
  //    -> Command; <- success complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));

  // Sequence 5 (HCI packets)
  //    -> Command; <- success complete
  //    -> Command; <- success complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));

  test_device()->StartCmdChannel(test_cmd_chan());
  test_device()->StartAclChannel(test_acl_chan());

  Status status;
  int status_cb_called = 0;
  auto status_cb = [&](Status cb_status) {
    status = cb_status;
    status_cb_called++;
  };

  int cb_called = 0;
  auto cb = [&](const EventPacket& event) { cb_called++; };

  // Sequence 1 (test)
  SequentialCommandRunner cmd_runner(dispatcher(), transport());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());

  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  EXPECT_EQ(1, cb_called);
  EXPECT_EQ(1, status_cb_called);
  EXPECT_EQ(StatusCode::kHardwareFailure, status.protocol_error());
  cb_called = 0;

  // Sequence 2 (test)
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  EXPECT_EQ(1, cb_called);
  EXPECT_EQ(2, status_cb_called);
  EXPECT_EQ(StatusCode::kReserved0, status.protocol_error());
  cb_called = 0;

  // Sequence 3 (test)
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  EXPECT_EQ(2, cb_called);
  EXPECT_EQ(3, status_cb_called);
  EXPECT_EQ(StatusCode::kReserved0, status.protocol_error());
  cb_called = 0;

  // Sequence 4 (test)
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  EXPECT_EQ(2, cb_called);
  EXPECT_EQ(4, status_cb_called);
  EXPECT_TRUE(status);
  cb_called = 0;
  status_cb_called = 0;

  // Sequence 5 (test) (no callback passed to QueueCommand)
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode));
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode));

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  EXPECT_EQ(0, cb_called);
  EXPECT_EQ(1, status_cb_called);
  EXPECT_TRUE(status);
}

TEST_F(HCI_SequentialCommandRunnerTest, SequentialCommandRunnerCancel) {
  auto command_bytes = CreateStaticByteBuffer(0xFF, 0xFF, 0x00);

  auto command_cmpl_error_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             1, 0xFF, 0xFF, StatusCode::kHardwareFailure);

  auto command_cmpl_success_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             1, 0xFF, 0xFF, StatusCode::kSuccess);

  // Sequence 1
  //   -> Command; <- success complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));

  // Sequence 2
  //   -> Command; <- success complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));

  // Sequence 3
  //   -> Command; <- success complete
  //   -> Command; <- error complete
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_error_bytes}));

  test_device()->StartCmdChannel(test_cmd_chan());
  test_device()->StartAclChannel(test_acl_chan());

  Status status;
  int status_cb_called = 0;
  auto status_cb = [&](Status cb_status) {
    status = cb_status;
    status_cb_called++;
  };

  int cb_called = 0;
  auto cb = [&](const EventPacket& event) { cb_called++; };

  // Sequence 1: Sequence will be cancelled after the first command.
  SequentialCommandRunner cmd_runner(dispatcher(), transport());
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  // Call RunCommands() and right away post a task to cancel the sequence. The
  // first command will go out but no successive packets should be sent.
  // status callbacks should be invoked
  // the command callback for the first command should run but no others.
  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());
  cmd_runner.Cancel();

  // Since |status_cb| is expected to not get called (which would normally quit
  // the message loop) - we run until we reach a steady-state waiting.
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());

  EXPECT_EQ(1, cb_called);
  EXPECT_EQ(1, status_cb_called);
  EXPECT_EQ(HostError::kCanceled, status.error());
  cb_called = 0;
  status_cb_called = 0;
  status = Status();

  // Sequence 2: Sequence will be cancelled after first command. This tests
  // canceling a sequence from a CommandCompleteCallback.
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), [&](const EventPacket& event) {
    bt_log(SPEW, "hci-test", "callback called");
    cmd_runner.Cancel();
    EXPECT_TRUE(cmd_runner.IsReady());
    EXPECT_FALSE(cmd_runner.HasQueuedCommands());
  });
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());

  // |status_cb| is expected to get called with kCanceled
  RunLoopUntilIdle();
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());

  EXPECT_EQ(0, cb_called);
  EXPECT_EQ(1, status_cb_called);
  EXPECT_EQ(HostError::kCanceled, status.error());

  // Sequence 3: Sequence will be cancelled after first command and immediately
  // followed by a second command which will fail. This tests canceling a
  // sequence and initiating a new one from a CommandCompleteCallback.
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), [&](const EventPacket& event) {
    cmd_runner.Cancel();
    EXPECT_TRUE(cmd_runner.IsReady());
    EXPECT_FALSE(cmd_runner.HasQueuedCommands());

    EXPECT_EQ(2, status_cb_called);
    EXPECT_EQ(HostError::kCanceled, status.error());

    // Queue multiple commands (only one will execute since TestController
    // will send back an error status.
    cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb);
    cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                            cb);  // <-- Should not run
    cmd_runner.RunCommands(status_cb);
  });
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // <-- Should not run
  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_TRUE(cmd_runner.HasQueuedCommands());

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());

  RunLoopUntilIdle();

  EXPECT_TRUE(cmd_runner.IsReady());
  EXPECT_FALSE(cmd_runner.HasQueuedCommands());

  // The cb queued from inside the first callback should have been called.
  EXPECT_EQ(1, cb_called);
  // The result callback should have been called with the failure result.
  EXPECT_EQ(3, status_cb_called);
  EXPECT_EQ(StatusCode::kHardwareFailure, status.protocol_error());
}

TEST_F(HCI_SequentialCommandRunnerTest, ParallelCommands) {
  // Need to signal to the queue that we can run more than one command at once.
  auto command_status_queue_increase =
      CreateStaticByteBuffer(kCommandStatusEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             StatusCode::kSuccess, 250, 0x00, 0x00);
  // HCI command with custom opcode FFFF.
  auto command_bytes = CreateStaticByteBuffer(0xFF, 0xFF, 0x00);
  auto command_status_error_bytes =
      CreateStaticByteBuffer(kCommandStatusEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             StatusCode::kHardwareFailure, 2, 0xFF, 0xFF);

  auto command_cmpl_error_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             2, 0xFF, 0xFF, StatusCode::kReserved0);

  auto command_cmpl_success_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             2, 0xFF, 0xFF, StatusCode::kSuccess);

  // HCI command with custom opcode F00F.
  auto command2_bytes = CreateStaticByteBuffer(0x0F, 0xF0, 0x00);
  auto command2_status_error_bytes =
      CreateStaticByteBuffer(kCommandStatusEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             StatusCode::kHardwareFailure, 2, 0x0F, 0xF0);

  auto command2_cmpl_error_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             2, 0x0F, 0xF0, StatusCode::kReserved0);

  auto command2_cmpl_success_bytes =
      CreateStaticByteBuffer(kCommandCompleteEventCode,
                             0x04,  // parameter_total_size (4 byte payload)
                             2, 0x0F, 0xF0, StatusCode::kSuccess);

  test_device()->StartCmdChannel(test_cmd_chan());
  test_device()->StartAclChannel(test_acl_chan());
  test_device()->SendCommandChannelPacket(command_status_queue_increase);

  // Parallel commands should all run before commands that require success.
  // command and command2 are answered in opposite order because they should be
  // sent simultaneously.
  test_device()->QueueCommandTransaction(CommandTransaction(command_bytes, {}));
  test_device()->QueueCommandTransaction(CommandTransaction(command2_bytes, {}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));
  test_device()->QueueCommandTransaction(
      CommandTransaction(command_bytes, {&command_cmpl_success_bytes}));

  int cb_called = 0;
  auto cb = [&](const auto&) { cb_called++; };

  int status_cb_called = 0;
  Status status(HostError::kFailed);
  auto status_cb = [&](Status cb_status) {
    status = cb_status;
    status_cb_called++;
  };

  SequentialCommandRunner cmd_runner(dispatcher(), transport());

  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb, false);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode2), cb, false);
  cmd_runner.QueueCommand(
      CommandPacket::New(kTestOpCode),
      [&](const auto&) {
        EXPECT_EQ(2, cb_called);
        cb_called++;
      },
      true);
  // We can also queue to the end of the queue without the last one being a
  // wait.
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb, false);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb, false);
  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());

  RunLoopUntilIdle();
  // The first two commands should have been sent but no responses are back yet.
  EXPECT_EQ(0, cb_called);

  // It should not matter if they get answered in opposite order.
  test_device()->SendCommandChannelPacket(command2_cmpl_success_bytes);
  test_device()->SendCommandChannelPacket(command_cmpl_success_bytes);
  RunLoopUntilIdle();

  EXPECT_EQ(5, cb_called);
  EXPECT_TRUE(status);
  EXPECT_EQ(1, status_cb_called);
  cb_called = 0;
  status_cb_called = 0;

  // If any simultaneous commands fail, the sequence fails and the command
  // sequence is terminated.
  test_device()->QueueCommandTransaction(CommandTransaction(command_bytes, {}));
  test_device()->QueueCommandTransaction(CommandTransaction(command2_bytes, {}));

  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode), cb, false);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode2), cb, false);
  cmd_runner.QueueCommand(CommandPacket::New(kTestOpCode),
                          cb);  // shouldn't run

  cmd_runner.RunCommands(status_cb);
  EXPECT_FALSE(cmd_runner.IsReady());

  RunLoopUntilIdle();
  // The first two commands should have been sent but no responses are back yet.
  EXPECT_EQ(0, cb_called);

  test_device()->SendCommandChannelPacket(command_status_error_bytes);
  test_device()->SendCommandChannelPacket(command2_cmpl_success_bytes);
  RunLoopUntilIdle();

  EXPECT_EQ(2, cb_called);
  EXPECT_EQ(1, status_cb_called);
  EXPECT_EQ(StatusCode::kHardwareFailure, status.protocol_error());
}

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