// Copyright 2019 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/fake_pairing_delegate.h"

#include <gtest/gtest.h>

#include "src/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"

namespace bt::gap {
namespace {

TEST(FakePairingDelegateTest, io_capability) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);
  EXPECT_EQ(sm::IOCapability::kDisplayYesNo, delegate.io_capability());
  delegate.set_io_capability(sm::IOCapability::kNoInputNoOutput);
  EXPECT_EQ(sm::IOCapability::kNoInputNoOutput, delegate.io_capability());
}

TEST(FakePairingDelegateTest, CompletePairing) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  bool cb_called = false;
  auto cb = [&cb_called](auto id, auto status) {
    cb_called = true;
    EXPECT_EQ(PeerId(5), id);
    EXPECT_EQ(ToResult(HostError::kFailed), status);
  };
  delegate.SetCompletePairingCallback(std::move(cb));
  delegate.CompletePairing(PeerId(5), ToResult(HostError::kFailed));
  EXPECT_TRUE(cb_called);
}

TEST(FakePairingDelegateTest, ConfirmPairing) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  bool cb_called = false;
  auto cb = [&cb_called](auto id, auto confirm) {
    cb_called = true;
    EXPECT_EQ(PeerId(5), id);
    ASSERT_TRUE(confirm);
    confirm(true);
  };
  delegate.SetConfirmPairingCallback(std::move(cb));
  delegate.ConfirmPairing(PeerId(5), [](bool) {});
  EXPECT_TRUE(cb_called);
}

TEST(FakePairingDelegateTest, DisplayPasskey) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  bool cb_called = false;
  auto cb = [&cb_called](auto id, auto passkey, auto method, auto confirm) {
    cb_called = true;
    EXPECT_EQ(PeerId(5), id);
    EXPECT_EQ(123456U, passkey);
    EXPECT_EQ(PairingDelegate::DisplayMethod::kComparison, method);
    ASSERT_TRUE(confirm);
    confirm(true);
  };
  delegate.SetDisplayPasskeyCallback(std::move(cb));
  delegate.DisplayPasskey(
      PeerId(5), 123456, PairingDelegate::DisplayMethod::kComparison, [](bool) {
      });
  EXPECT_TRUE(cb_called);
}

TEST(FakePairingDelegateTest, RequestPasskey) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  bool cb_called = false;
  auto cb = [&cb_called](auto id, auto respond) {
    cb_called = true;
    EXPECT_EQ(PeerId(5), id);
    ASSERT_TRUE(respond);
    respond(-1);
  };
  delegate.SetRequestPasskeyCallback(std::move(cb));
  delegate.RequestPasskey(PeerId(5), [](uint64_t) {});
  EXPECT_TRUE(cb_called);
}

TEST(FakePairingDelegateTest, UnexpectedCalls) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  // Each of the following calls should generate failure(s).
  // delegate.CompletePairing(PeerId(5), ToResult(HostError::kFailed));
  // delegate.ConfirmPairing(PeerId(5), [](bool) {});
  // delegate.DisplayPasskey(PeerId(5), 123456,
  // PairingDelegate::DisplayMethod::kComparison,
  //                         [](bool) {});
  // delegate.RequestPasskey(PeerId(5), [](uint64_t) {});
}

TEST(FakePairingDelegateTest, ExpectCallNotCalled) {
  FakePairingDelegate delegate(sm::IOCapability::kDisplayYesNo);

  // delegate.SetCompletePairingCallback([](auto, auto) {});
  // delegate.SetConfirmPairingCallback([](auto, auto) {});
  // delegate.SetDisplayPasskeyCallback([](auto, auto, auto, auto) {});
  // delegate.SetRequestPasskeyCallback([](auto, auto) {});
  // Each of the preceding calls should generate failure(s) when |delegate| goes
  // out of scope.
}

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