// Copyright 2021 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/host.h"

#include <lib/inspect/testing/cpp/inspect.h>
#include <lib/zx/channel.h>

#include <memory>

#include "lib/gtest/test_loop_fixture.h"

namespace bthost::testing {

using TestingBase = ::gtest::TestLoopFixture;

static zx_status_t hosttest_open_command_channel(void *ctx, zx_handle_t in);
static zx_status_t hosttest_open_acl_data_channel(void *ctx, zx_handle_t in);
static zx_status_t hosttest_open_sco_data_channel(void *ctx, zx_handle_t in);
static zx_status_t hosttest_open_snoop_channel(void *ctx, zx_handle_t in);

static bt_hci_protocol_ops_t hosttest_hci_protocol_ops = {
    .open_command_channel = hosttest_open_command_channel,
    .open_acl_data_channel = hosttest_open_acl_data_channel,
    .open_sco_channel = hosttest_open_sco_data_channel,
    .open_snoop_channel = hosttest_open_snoop_channel,
};

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

  void SetUp() override { host_ = Host::Create(hci_proto(), std::nullopt); }

  void TearDown() override {
    host_->ShutDown();
    host_ = nullptr;
    TestingBase::TearDown();
  }

  zx_status_t OpenCommandChannel(zx_handle_t in) {
    EXPECT_FALSE(cmd_channel_.has_value());
    cmd_channel_ = in;
    return ZX_OK;
  }

  zx_status_t OpenAclDataChannel(zx_handle_t in) {
    EXPECT_FALSE(acl_channel_.has_value());
    acl_channel_ = in;
    return ZX_OK;
  }

  zx_status_t OpenSnoopChannel(zx_handle_t in) {
    EXPECT_FALSE(snoop_channel_.has_value());
    snoop_channel_ = in;
    return ZX_OK;
  }

 protected:
  Host *host() const { return host_.get(); }

 private:
  fbl::RefPtr<Host> host_;

  // The channels that are provided to the device on initialization.
  // TODO(fxbug.dev/90952): Optionally wire these up to a TestController or MockController.
  std::optional<zx_handle_t> cmd_channel_;
  std::optional<zx_handle_t> acl_channel_;
  std::optional<zx_handle_t> snoop_channel_;

  bt_hci_protocol_t hci_proto() {
    bt_hci_protocol_t hci_proto;
    hci_proto.ops = &hosttest_hci_protocol_ops;
    hci_proto.ctx = this;
    return hci_proto;
  }

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(HostTest);
};

zx_status_t hosttest_open_command_channel(void *ctx, zx_handle_t in) {
  HostTest *test = static_cast<HostTest *>(ctx);
  return test->OpenCommandChannel(in);
}

zx_status_t hosttest_open_acl_data_channel(void *ctx, zx_handle_t in) {
  HostTest *test = static_cast<HostTest *>(ctx);
  return test->OpenAclDataChannel(in);
}

zx_status_t hosttest_open_sco_data_channel(void *ctx, zx_handle_t in) {
  zx_handle_close(in);
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t hosttest_open_snoop_channel(void *ctx, zx_handle_t in) {
  HostTest *test = static_cast<HostTest *>(ctx);
  return test->OpenSnoopChannel(in);
}

namespace {

TEST_F(HostTest, InitializeFailsWhenCommandTimesOut) {
  inspect::Inspector inspector;
  auto bt_host_node = inspector.GetRoot().CreateChild("bt-host");

  std::optional<bool> init_cb_result;
  bool error_cb_called = false;
  host()->Initialize(
      bt_host_node, [&](bool success) { init_cb_result = success; },
      [&]() { error_cb_called = true; });

  // Any command sent to the command channel will time out, so run the loop until it does, and the
  // transport should signal failure, which should call our error callback.
  constexpr zx::duration kCommandTimeout = zx::sec(12);

  RunLoopFor(kCommandTimeout);

  // Initialization will fail before the error callback would be called (the error callback is only
  // called after successful initialization).
  EXPECT_FALSE(error_cb_called);
  // Initialization also failed, since the adapter initialization is what was being done when the
  // timeout happened.
  EXPECT_TRUE(init_cb_result.has_value());
  EXPECT_FALSE(init_cb_result.value());
}

}  // namespace
}  // namespace bthost::testing
