// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "faced/dbus_adaptor.h"

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/files/scoped_file.h>
#include <base/posix/eintr_wrapper.h>
#include <base/run_loop.h>
#include <base/test/bind.h>
#include <base/test/task_environment.h>
#include <brillo/dbus/mock_dbus_method_response.h>
#include <dbus/bus.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <gmock/gmock-nice-strict.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "faced/face_auth_service.h"

namespace faced {

namespace {

using ::brillo::dbus_utils::MockDBusMethodResponse;
using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrictMock;
using ReceiveOnIpcThreadCallback =
    FaceAuthServiceInterface::ReceiveOnIpcThreadCallback;

class MockFaceAuthService : public FaceAuthServiceInterface {
 public:
  MOCK_METHOD(void,
              ReceiveMojoInvitation,
              (base::ScopedFD fd,
               ReceiveOnIpcThreadCallback callback,
               scoped_refptr<base::TaskRunner> callback_runner),
              (override));
};

base::ScopedFD CreateFakeFd() {
  // Create a pair of connected sockets.
  int fds[2];
  CHECK_EQ(0,
           HANDLE_EINTR(socketpair(AF_UNIX, SOCK_STREAM, /*protocol=*/0, fds)));

  // Close one side of the pair, and return the other.
  close(fds[1]);
  return base::ScopedFD(fds[0]);
}

}  // namespace

TEST(DBusAdaptorTest, BootstrapMojoConnection) {
  StrictMock<MockFaceAuthService> mock_service;
  ON_CALL(mock_service, ReceiveMojoInvitation(_, _, _))
      .WillByDefault(
          Invoke([&](base::ScopedFD fd, ReceiveOnIpcThreadCallback callback,
                     scoped_refptr<base::TaskRunner> callback_runner) {
            callback_runner->PostTask(
                FROM_HERE, base::BindOnce(std::move(callback), true));
          }));
  EXPECT_CALL(mock_service, ReceiveMojoInvitation).Times(1);

  // Expect call to OnBootstrapMojoConnectionResponse
  auto response = std::make_unique<MockDBusMethodResponse<>>();
  bool called = false;
  response->set_return_callback(
      base::BindLambdaForTesting([&called]() { called = true; }));

  scoped_refptr<dbus::Bus> bus =
      base::MakeRefCounted<dbus::Bus>(dbus::Bus::Options{});
  auto dbus_adaptor = std::make_unique<DBusAdaptor>(bus, mock_service);

  base::RunLoop loop;
  dbus_adaptor->BootstrapMojoConnection(std::move(response), CreateFakeFd());

  loop.RunUntilIdle();
  EXPECT_TRUE(called);
}

TEST(DBusAdaptorTest, BootstrapMojoConnectionFailure) {
  StrictMock<MockFaceAuthService> mock_service;
  ON_CALL(mock_service, ReceiveMojoInvitation(_, _, _))
      .WillByDefault(
          Invoke([&](base::ScopedFD fd, ReceiveOnIpcThreadCallback callback,
                     scoped_refptr<base::TaskRunner> callback_runner) {
            callback_runner->PostTask(
                FROM_HERE, base::BindOnce(std::move(callback), false));
          }));
  EXPECT_CALL(mock_service, ReceiveMojoInvitation).Times(1);

  base::RunLoop loop;

  // Expect error to propagate to DBusMethodResponse::ReplyWithError
  auto response = std::make_unique<MockDBusMethodResponse<>>();
  ON_CALL(*response, ReplyWithError(_))
      .WillByDefault(Invoke(
          [&](const brillo::Error* error) { loop.QuitClosure().Run(); }));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(1);

  scoped_refptr<dbus::Bus> bus =
      base::MakeRefCounted<dbus::Bus>(dbus::Bus::Options{});
  auto dbus_adaptor = std::make_unique<DBusAdaptor>(bus, mock_service);

  dbus_adaptor->BootstrapMojoConnection(std::move(response), CreateFakeFd());

  loop.Run();
}

}  // namespace faced
