// 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/public/pw_bluetooth_sapphire/internal/host/gap/bredr_connection_request.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <pw_async/fake_dispatcher_fixture.h>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/inspect.h"

namespace bt::gap {
namespace {

using namespace inspect::testing;

const DeviceAddress kTestAddr(DeviceAddress::Type::kBREDR, {1});
const PeerId kPeerId;
constexpr hci::Error RetryableError =
    ToResult(pw::bluetooth::emboss::StatusCode::PAGE_TIMEOUT).error_value();

using BrEdrConnectionRequestTests = pw::async::test::FakeDispatcherFixture;

TEST_F(BrEdrConnectionRequestTests, IncomingRequestStatusTracked) {
  // A freshly created request is not yet incoming
  auto req = BrEdrConnectionRequest(dispatcher(),
                                    kTestAddr,
                                    kPeerId,
                                    Peer::InitializingConnectionToken([] {}));
  EXPECT_FALSE(req.HasIncoming());

  req.BeginIncoming();
  // We should now have an incoming request, but still not an outgoing
  EXPECT_TRUE(req.HasIncoming());
  EXPECT_FALSE(req.AwaitingOutgoing());

  // A completed request is no longer incoming
  req.CompleteIncoming();
  EXPECT_FALSE(req.HasIncoming());
}

TEST_F(BrEdrConnectionRequestTests, CallbacksExecuted) {
  bool callback_called = false;
  bool token_destroyed = false;
  auto req = BrEdrConnectionRequest(
      dispatcher(),
      kTestAddr,
      kPeerId,
      Peer::InitializingConnectionToken(
          [&token_destroyed] { token_destroyed = true; }),
      [&callback_called](auto, auto) { callback_called = true; });

  // A freshly created request with a callback is awaiting outgoing
  EXPECT_TRUE(req.AwaitingOutgoing());
  // Notifying callbacks triggers the callback
  req.NotifyCallbacks(fit::ok(), [&]() {
    EXPECT_TRUE(token_destroyed);
    return nullptr;
  });
  EXPECT_TRUE(token_destroyed);
  EXPECT_TRUE(callback_called);
}

#ifndef NINSPECT
TEST_F(BrEdrConnectionRequestTests, Inspect) {
  // inspector must outlive request
  inspect::Inspector inspector;
  BrEdrConnectionRequest req(dispatcher(),
                             kTestAddr,
                             kPeerId,
                             Peer::InitializingConnectionToken([] {}),
                             [](auto, auto) {});
  req.BeginIncoming();
  req.AttachInspect(inspector.GetRoot(), "request_name");

  auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
  EXPECT_THAT(
      hierarchy.value(),
      ChildrenMatch(ElementsAre(NodeMatches(AllOf(
          NameMatches("request_name"),
          PropertyList(UnorderedElementsAre(
              StringIs("peer_id", kPeerId.ToString()),
              UintIs("callbacks", 1u),
              BoolIs("has_incoming", true),
              IntIs("first_create_connection_request_timestamp", -1))))))));
}
#endif  // NINSPECT

class BrEdrConnectionRequestLoopTest
    : public pw::async::test::FakeDispatcherFixture {
 protected:
  using OnComplete = BrEdrConnectionRequest::OnComplete;

  BrEdrConnectionRequestLoopTest()
      : req_(dispatcher(),
             kTestAddr,
             kPeerId,
             Peer::InitializingConnectionToken([] {}),
             [this](hci::Result<> res, BrEdrConnection* conn) {
               if (handler_) {
                 handler_(res, conn);
               }
             }) {
    // By default, an outbound ConnectionRequest with a complete handler that
    // just logs the result.
    handler_ = [](hci::Result<> res, auto /*ignore*/) {
      bt_log(INFO,
             "gap-bredr-test",
             "outbound connection request complete: %s",
             bt_str(res));
    };
  }

  void set_on_complete(BrEdrConnectionRequest::OnComplete handler) {
    handler_ = std::move(handler);
  }

  BrEdrConnectionRequest& connection_req() { return req_; }

 private:
  BrEdrConnectionRequest req_;
  OnComplete handler_;
};
using BrEdrConnectionRequestLoopDeathTest = BrEdrConnectionRequestLoopTest;

TEST_F(BrEdrConnectionRequestLoopTest,
       RetryableErrorCodeShouldRetryAfterFirstCreateConnection) {
  connection_req().RecordHciCreateConnectionAttempt();
  RunFor(std::chrono::seconds(1));
  EXPECT_TRUE(connection_req().ShouldRetry(RetryableError));
}

TEST_F(BrEdrConnectionRequestLoopTest,
       ShouldntRetryBeforeFirstCreateConnection) {
  EXPECT_FALSE(connection_req().ShouldRetry(RetryableError));
}

TEST_F(BrEdrConnectionRequestLoopTest, ShouldntRetryWithNonRetriableErrorCode) {
  connection_req().RecordHciCreateConnectionAttempt();
  RunFor(std::chrono::seconds(1));
  EXPECT_FALSE(connection_req().ShouldRetry(hci::Error(HostError::kCanceled)));
}

TEST_F(BrEdrConnectionRequestLoopTest, ShouldntRetryAfterThirtySeconds) {
  connection_req().RecordHciCreateConnectionAttempt();
  RunFor(std::chrono::seconds(15));
  // Should be OK to retry after 15 seconds
  EXPECT_TRUE(connection_req().ShouldRetry(RetryableError));
  connection_req().RecordHciCreateConnectionAttempt();

  // Should still be OK to retry, even though we've already retried
  RunFor(std::chrono::seconds(14));
  EXPECT_TRUE(connection_req().ShouldRetry(RetryableError));
  connection_req().RecordHciCreateConnectionAttempt();

  RunFor(std::chrono::seconds(1));
  EXPECT_FALSE(connection_req().ShouldRetry(RetryableError));
}

}  // namespace
}  // namespace bt::gap
