// 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/gap/low_energy_connector.h"

#include <lib/async/default.h>

#include "src/connectivity/bluetooth/core/bt-host/gap/peer_cache.h"

namespace bt::gap::internal {

namespace {

// During the initial connection to a peripheral we use the initial high
// duty-cycle parameters to ensure that initiating procedures (bonding,
// encryption setup, service discovery) are completed quickly. Once these
// procedures are complete, we will change the connection interval to the
// peripheral's preferred connection parameters (see v5.0, Vol 3, Part C,
// Section 9.3.12).
static const hci::LEPreferredConnectionParameters kInitialConnectionParameters(
    kLEInitialConnIntervalMin, kLEInitialConnIntervalMax, /*max_latency=*/0,
    hci::defaults::kLESupervisionTimeout);

constexpr int kMaxConnectionAttempts = 3;
constexpr int kRetryExponentialBackoffBase = 2;

constexpr const char* kInspectPeerIdPropertyName = "peer_id";
constexpr const char* kInspectConnectionAttemptPropertyName = "connection_attempt";
constexpr const char* kInspectStatePropertyName = "state";
constexpr const char* kInspectIsOutboundPropertyName = "is_outbound";

}  // namespace

std::unique_ptr<LowEnergyConnector> LowEnergyConnector::CreateOutboundConnector(
    PeerId peer_id, LowEnergyConnectionOptions options, hci::LowEnergyConnector* connector,
    zx::duration request_timeout, fxl::WeakPtr<hci::Transport> transport, PeerCache* peer_cache,
    fxl::WeakPtr<LowEnergyDiscoveryManager> discovery_manager,
    fxl::WeakPtr<LowEnergyConnectionManager> conn_mgr, fbl::RefPtr<l2cap::L2cap> l2cap,
    fxl::WeakPtr<gatt::GATT> gatt, ResultCallback cb) {
  return std::unique_ptr<LowEnergyConnector>(new LowEnergyConnector(
      /*outbound=*/true, peer_id, /*connection=*/nullptr, options, connector, request_timeout,
      transport, peer_cache, conn_mgr, discovery_manager, l2cap, gatt, std::move(cb)));
}

std::unique_ptr<LowEnergyConnector> LowEnergyConnector::CreateInboundConnector(
    PeerId peer_id, std::unique_ptr<hci::Connection> connection, LowEnergyConnectionOptions options,
    fxl::WeakPtr<hci::Transport> transport, PeerCache* peer_cache,
    fxl::WeakPtr<LowEnergyConnectionManager> conn_mgr, fbl::RefPtr<l2cap::L2cap> l2cap,
    fxl::WeakPtr<gatt::GATT> gatt, ResultCallback cb) {
  return std::unique_ptr<LowEnergyConnector>(new LowEnergyConnector(
      /*outbound=*/false, peer_id, std::move(connection), options, /*connector=*/nullptr,
      /*request_timeout=*/zx::duration(0), transport, peer_cache, conn_mgr,
      /*discovery_manager=*/nullptr, l2cap, gatt, std::move(cb)));
}

LowEnergyConnector::LowEnergyConnector(
    bool outbound, PeerId peer_id, std::unique_ptr<hci::Connection> connection,
    LowEnergyConnectionOptions options, hci::LowEnergyConnector* connector,
    zx::duration request_timeout, fxl::WeakPtr<hci::Transport> transport, PeerCache* peer_cache,
    fxl::WeakPtr<LowEnergyConnectionManager> conn_mgr,
    fxl::WeakPtr<LowEnergyDiscoveryManager> discovery_manager, fbl::RefPtr<l2cap::L2cap> l2cap,
    fxl::WeakPtr<gatt::GATT> gatt, ResultCallback cb)
    : state_(State::kIdle, /*convert=*/[](auto s) { return StateToString(s); }),
      peer_id_(peer_id),
      peer_cache_(peer_cache),
      l2cap_(l2cap),
      gatt_(gatt),
      is_outbound_(outbound),
      hci_request_timeout_(request_timeout),
      options_(options),
      result_cb_(std::move(cb)),
      hci_connector_(connector),
      connection_attempt_(0),
      interrogator_(peer_cache_, transport),
      discovery_manager_(std::move(discovery_manager)),
      transport_(transport),
      le_connection_manager_(conn_mgr),
      weak_ptr_factory_(this) {
  ZX_ASSERT(le_connection_manager_);
  ZX_ASSERT(transport_);
  ZX_ASSERT(peer_cache_);

  auto peer = peer_cache_->FindById(peer_id_);
  ZX_ASSERT(peer);
  peer_address_ = peer->address();

  if (is_outbound_) {
    ZX_ASSERT(discovery_manager_);
    ZX_ASSERT(!connection);
    ZX_ASSERT(hci_connector_);
    ZX_ASSERT(hci_request_timeout_.get() != 0);

    if (options.auto_connect) {
      RequestCreateConnection();
    } else {
      StartScanningForPeer();
    }
  } else {
    ZX_ASSERT(connection);
    ZX_ASSERT(peer_address_.value() == connection->peer_address().value());

    InitializeConnection(std::move(connection));
    StartInterrogation();
  }
}

LowEnergyConnector::~LowEnergyConnector() {
  if (*state_ != State::kComplete && *state_ != State::kFailed) {
    bt_log(WARN, "gap-le", "destroying LowEnergyConnector before procedure completed (peer: %s)",
           bt_str(peer_id_));
    NotifyFailure(hci::Status(HostError::kCanceled));
  }

  if (hci_connector_ && hci_connector_->request_pending()) {
    // NOTE: LowEnergyConnector will be unable to wait for the connection to be canceled. The
    // hci::LowEnergyConnector may still be waiting to cancel the connection when a later
    // gap::internal::LowEnergyConnector is created.
    hci_connector_->Cancel();
  }

  interrogator_.Cancel(peer_id_);
}

void LowEnergyConnector::Cancel() {
  bt_log(INFO, "gap-le", "canceling connector (peer: %s, state: %s)", bt_str(peer_id_),
         StateToString(*state_));

  switch (*state_) {
    case State::kStartingScanning:
      discovery_session_.reset();
      NotifyFailure(hci::Status(HostError::kCanceled));
      break;
    case State::kScanning:
      discovery_session_.reset();
      scan_timeout_task_.reset();
      NotifyFailure(hci::Status(HostError::kCanceled));
      break;
    case State::kConnecting:
      // The connector will call the result callback with a cancelled result.
      hci_connector_->Cancel();
      break;
    case State::kInterrogating:
      // The interrogator will call the result callback with a cancelled result.
      interrogator_.Cancel(peer_id_);
      break;
    case State::kPauseBeforeConnectionRetry:
      request_create_connection_task_.Cancel();
      NotifyFailure(hci::Status(HostError::kCanceled));
      break;
    case State::kAwaitingConnectionFailedToBeEstablishedDisconnect:
      // Waiting for disconnect complete, nothing to do.
    case State::kComplete:
    case State::kFailed:
      // Cancelling completed/failed connector is a no-op.
      break;
    case State::kIdle:
      // It should not be possible to cancel during kIdle as the state is immediately changed.
      ZX_PANIC("Cancel called during kIdle");
  }
}

void LowEnergyConnector::AttachInspect(inspect::Node& parent, std::string name) {
  inspect_node_ = parent.CreateChild(name);
  inspect_properties_.peer_id =
      inspect_node_.CreateString(kInspectPeerIdPropertyName, peer_id_.ToString());
  connection_attempt_.AttachInspect(inspect_node_, kInspectConnectionAttemptPropertyName);
  state_.AttachInspect(inspect_node_, kInspectStatePropertyName);
  inspect_properties_.is_outbound =
      inspect_node_.CreateBool(kInspectIsOutboundPropertyName, is_outbound_);
}

const char* LowEnergyConnector::StateToString(State state) {
  switch (state) {
    case State::kIdle:
      return "Idle";
    case State::kStartingScanning:
      return "StartingScanning";
    case State::kScanning:
      return "Scanning";
    case State::kConnecting:
      return "Connecting";
    case State::kInterrogating:
      return "Interrogating";
    case State::kAwaitingConnectionFailedToBeEstablishedDisconnect:
      return "AwaitingConnectionFailedToBeEstablishedDisconnect";
    case State::kPauseBeforeConnectionRetry:
      return "PauseBeforeConnectionRetry";
    case State::kComplete:
      return "Complete";
    case State::kFailed:
      return "Failed";
  }
}

void LowEnergyConnector::StartScanningForPeer() {
  auto self = weak_ptr_factory_.GetWeakPtr();

  state_.Set(State::kStartingScanning);

  discovery_manager_->StartDiscovery(/*active=*/false, [self](auto session) {
    if (self) {
      self->OnScanStart(std::move(session));
    }
  });
}

void LowEnergyConnector::OnScanStart(LowEnergyDiscoverySessionPtr session) {
  if (*state_ == State::kFailed) {
    return;
  }
  ZX_ASSERT(*state_ == State::kStartingScanning);

  // Failed to start scan, abort connection procedure.
  if (!session) {
    bt_log(INFO, "gap-le", "failed to start scan (peer: %s)", bt_str(peer_id_));
    NotifyFailure(hci::Status(HostError::kFailed));
    return;
  }

  bt_log(INFO, "gap-le", "started scanning for pending connection (peer: %s)", bt_str(peer_id_));
  state_.Set(State::kScanning);

  auto self = weak_ptr_factory_.GetWeakPtr();
  scan_timeout_task_.emplace([this] {
    ZX_ASSERT(*state_ == State::kScanning);
    bt_log(INFO, "gap-le", "scan for pending connection timed out (peer: %s)", bt_str(peer_id_));
    NotifyFailure(hci::Status(HostError::kTimedOut));
  });
  // The scan timeout may include time during which scanning is paused.
  scan_timeout_task_->PostDelayed(async_get_default_dispatcher(), kLEGeneralCepScanTimeout);

  discovery_session_ = std::move(session);
  discovery_session_->filter()->set_connectable(true);

  // The error callback must be set before the result callback in case the result callback is called
  // synchronously.
  discovery_session_->set_error_callback([self] {
    ZX_ASSERT(self->state_.value() == State::kScanning);
    bt_log(INFO, "gap-le", "discovery error while scanning for peer (peer: %s)",
           bt_str(self->peer_id_));
    self->scan_timeout_task_.reset();
    self->NotifyFailure(hci::Status(HostError::kFailed));
  });

  discovery_session_->SetResultCallback([self](auto& peer) {
    ZX_ASSERT(self->state_.value() == State::kScanning);

    if (peer.identifier() != self->peer_id_) {
      return;
    }

    bt_log(INFO, "gap-le", "discovered peer for pending connection (peer: %s)",
           bt_str(self->peer_id_));

    self->scan_timeout_task_.reset();
    self->discovery_session_->Stop();

    self->RequestCreateConnection();
  });
}

void LowEnergyConnector::RequestCreateConnection() {
  // Scanning may be skipped. When the peer disconnects during/after interrogation, a retry may be
  // initiated by calling this method.
  ZX_ASSERT(*state_ == State::kIdle || *state_ == State::kScanning ||
            *state_ == State::kPauseBeforeConnectionRetry);

  // Pause discovery until connection complete.
  auto pause_token = discovery_manager_->PauseDiscovery();

  auto self = weak_ptr_factory_.GetWeakPtr();
  auto status_cb = [self, pause = std::move(pause_token)](hci::Status status, auto link) {
    if (self) {
      self->OnConnectResult(status, std::move(link));
    }
  };

  state_.Set(State::kConnecting);

  // TODO(fxbug.dev/70199): Use slow interval & window for auto connections during background scan.
  ZX_ASSERT(hci_connector_->CreateConnection(
      /*use_whitelist=*/false, peer_address_, kLEScanFastInterval, kLEScanFastWindow,
      kInitialConnectionParameters, std::move(status_cb), hci_request_timeout_));
}

void LowEnergyConnector::OnConnectResult(hci::Status status, hci::ConnectionPtr link) {
  if (!status) {
    bt_log(INFO, "gap-le", "failed to connect to peer (id: %s, status: %s)", bt_str(peer_id_),
           bt_str(status));

    NotifyFailure(status);
    return;
  }
  ZX_ASSERT(link);

  bt_log(INFO, "gap-le", "connection request successful (peer: %s)", bt_str(peer_id_));

  InitializeConnection(std::move(link));
  StartInterrogation();
}

void LowEnergyConnector::InitializeConnection(hci::ConnectionPtr link) {
  ZX_ASSERT(link);

  auto peer_disconnect_cb = fit::bind_member(this, &LowEnergyConnector::OnPeerDisconnect);
  auto error_cb = [this]() { NotifyFailure(); };

  connection_ = std::make_unique<LowEnergyConnection>(
      peer_id_, std::move(link), options_, peer_disconnect_cb, error_cb, le_connection_manager_,
      l2cap_, gatt_, transport_);
}

void LowEnergyConnector::StartInterrogation() {
  ZX_ASSERT((is_outbound_ && *state_ == State::kConnecting) ||
            (!is_outbound_ && *state_ == State::kIdle));
  ZX_ASSERT(connection_);

  state_.Set(State::kInterrogating);
  interrogator_.Start(peer_id_, connection_->handle(),
                      fit::bind_member(this, &LowEnergyConnector::OnInterrogationComplete));
}

void LowEnergyConnector::OnInterrogationComplete(hci::Status status) {
  // If a disconnect event is received before interrogation completes, state_ will be either kFailed
  // or kPauseBeforeConnectionRetry depending on the status of the disconnect.
  ZX_ASSERT(*state_ == State::kInterrogating || *state_ == State::kFailed ||
            *state_ == State::kPauseBeforeConnectionRetry);
  if (*state_ == State::kFailed || *state_ == State::kPauseBeforeConnectionRetry) {
    return;
  }

  ZX_ASSERT(connection_);

  // If the controller responds to an interrogation command with the 0x3e
  // "kConnectionFailedToBeEstablished" error, it will send a Disconnection Complete event soon
  // after. Wait for this event before initating a retry.
  if (status.is_protocol_error() &&
      status.protocol_error() == hci::kConnectionFailedToBeEstablished) {
    bt_log(INFO, "gap-le",
           "Received kConnectionFailedToBeEstablished during interrogation. Waiting for Disconnect "
           "Complete. (peer: %s)",
           bt_str(peer_id_));
    state_.Set(State::kAwaitingConnectionFailedToBeEstablishedDisconnect);
    return;
  }

  if (!status.is_success()) {
    bt_log(INFO, "gap-le", "interrogation failed with %s (peer: %s)", bt_str(status),
           bt_str(peer_id_));
    NotifyFailure();
    return;
  }

  NotifySuccess();
}

void LowEnergyConnector::OnPeerDisconnect(hci::StatusCode status) {
  // The peer can't disconnect while scanning or connecting, and we unregister from
  // disconnects after kFailed & kComplete.
  ZX_ASSERT_MSG(*state_ == State::kInterrogating ||
                    *state_ == State::kAwaitingConnectionFailedToBeEstablishedDisconnect,
                "Received peer disconnect during invalid state (state: %s, status: %s)",
                StateToString(*state_), bt_str(hci::Status(status)));
  if (*state_ == State::kInterrogating &&
      status != hci::StatusCode::kConnectionFailedToBeEstablished) {
    NotifyFailure(hci::Status(status));
    return;
  }

  // state_ is kAwaitingConnectionFailedToBeEstablished or kInterrogating with a 0x3e error, so
  // retry connection
  if (!MaybeRetryConnection()) {
    NotifyFailure(hci::Status(status));
  }
}

bool LowEnergyConnector::MaybeRetryConnection() {
  // Only retry outbound connections.
  if (is_outbound_ && *connection_attempt_ < kMaxConnectionAttempts - 1) {
    connection_.reset();
    state_.Set(State::kPauseBeforeConnectionRetry);

    // Exponential backoff (2s, 4s, 8s, ...)
    zx::duration retry_delay = zx::sec(kRetryExponentialBackoffBase << *connection_attempt_);

    connection_attempt_.Set(*connection_attempt_ + 1);
    bt_log(INFO, "gap-le", "Retrying connection in %lds (peer: %s, attempt: %d)",
           retry_delay.to_secs(), bt_str(peer_id_), *connection_attempt_);
    request_create_connection_task_.PostDelayed(async_get_default_dispatcher(), retry_delay);
    return true;
  }
  return false;
}

void LowEnergyConnector::NotifySuccess() {
  ZX_ASSERT(*state_ == State::kInterrogating);
  ZX_ASSERT(connection_);
  ZX_ASSERT(result_cb_);

  state_.Set(State::kComplete);

  // LowEnergyConnectionManager should immediately set handlers to replace these ones.
  connection_->set_peer_disconnect_callback([peer_id = peer_id_](auto) {
    ZX_PANIC("Peer disconnected without handler set (peer: %s)", bt_str(peer_id));
  });

  connection_->set_error_callback([peer_id = peer_id_]() {
    ZX_PANIC("connection error without handler set (peer: %s)", bt_str(peer_id));
  });

  result_cb_(fit::ok(std::move(connection_)));
}

void LowEnergyConnector::NotifyFailure(hci::Status status) {
  state_.Set(State::kFailed);
  // The result callback must only be called once, so extraneous failures should be ignored.
  if (result_cb_) {
    result_cb_(fit::error(status));
  }
}

}  // namespace bt::gap::internal
