// 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 "src/connectivity/bluetooth/core/bt-host/gap/interrogator.h"

#include <lib/async/default.h>

#include "src/connectivity/bluetooth/core/bt-host/common/status.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/status.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller_test.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_peer.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/test_controller.h"

namespace bt::gap {

constexpr hci::ConnectionHandle kConnectionHandle = 0x0BAA;
const DeviceAddress kTestDevAddr(DeviceAddress::Type::kBREDR, {1});

class TestInterrogator final : public Interrogator {
 public:
  // Reuse constructor
  using Interrogator::Interrogator;
  ~TestInterrogator() override = default;

  using InterrogationRefPtr = Interrogator::InterrogationRefPtr;

  void set_send_commands_cb(fit::function<void(InterrogationRefPtr)> cb) {
    send_commands_cb_ = std::move(cb);
  }

 private:
  // Interrogator overrides:

  void SendCommands(InterrogationRefPtr interrogation) override {
    if (send_commands_cb_) {
      send_commands_cb_(std::move(interrogation));
    }
  }

  fit::function<void(InterrogationRefPtr)> send_commands_cb_;
};

using InterrogationRefPtr = TestInterrogator::InterrogationRefPtr;

using TestingBase = bt::testing::FakeControllerTest<bt::testing::TestController>;
class InterrogatorTest : public TestingBase {
 public:
  InterrogatorTest() = default;
  ~InterrogatorTest() override = default;

  void SetUp() override {
    TestingBase::SetUp();

    peer_cache_ =
        std::make_unique<PeerCache>(inspector_.GetRoot().CreateChild(PeerCache::kInspectNodeName));
    auto hci = transport();

    interrogator_ =
        std::make_unique<TestInterrogator>(peer_cache_.get(), hci, async_get_default_dispatcher());

    StartTestDevice();
  }

  void TearDown() override {
    RunLoopUntilIdle();
    test_device()->Stop();
    interrogator_ = nullptr;
    peer_cache_ = nullptr;
    TestingBase::TearDown();
  }

 protected:
  PeerCache* peer_cache() const { return peer_cache_.get(); }

  TestInterrogator* interrogator() const { return interrogator_.get(); }

 private:
  inspect::Inspector inspector_;
  std::unique_ptr<PeerCache> peer_cache_;
  std::unique_ptr<TestInterrogator> interrogator_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(InterrogatorTest);
};

using GAP_InterrogatorTest = InterrogatorTest;

TEST_F(GAP_InterrogatorTest, DroppingInterrogationRefCompletesInterrogation) {
  std::optional<InterrogationRefPtr> ref;
  interrogator()->set_send_commands_cb([&ref](InterrogationRefPtr r) { ref = std::move(r); });

  auto* peer = peer_cache()->NewPeer(kTestDevAddr, true);

  ASSERT_FALSE(ref.has_value());

  std::optional<hci::Status> result;
  interrogator()->Start(peer->identifier(), kConnectionHandle,
                        [&](hci::Status status) { result = status; });

  ASSERT_TRUE(ref.has_value());
  EXPECT_FALSE(result.has_value());

  // Dropping ref should call result callback with success status.
  ref.reset();

  ASSERT_TRUE(result.has_value());
  EXPECT_TRUE(result->is_success());
}

}  // namespace bt::gap
