// Copyright 2020 The Chromium OS 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 "ocr/daemon.h"

#include <memory>
#include <string>
#include <sysexits.h>
#include <utility>

#include <base/bind.h>
#include <base/callback.h>
#include <base/check.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/unguessable_token.h>
#include <dbus/object_path.h>
#include <chromeos/dbus/service_constants.h>
#include <mojo/public/cpp/platform/platform_channel_endpoint.h>
#include <mojo/public/cpp/system/invitation.h>
#include <mojo/core/embedder/embedder.h>

#include "ocr/ocr_service_impl.h"

namespace ocr {

OcrDaemon::OcrDaemon() : brillo::DBusServiceDaemon(kOcrServiceName) {
  ocr_service_impl_ = std::make_unique<OcrServiceImpl>();
  ocr_service_impl_->SetOnDisconnectCallback(base::BindRepeating(
      &OcrDaemon::OnDisconnect, weak_ptr_factory_.GetWeakPtr()));
}

OcrDaemon::~OcrDaemon() = default;

int OcrDaemon::OnInit() {
  int return_code = brillo::DBusServiceDaemon::OnInit();
  if (return_code != EX_OK)
    return return_code;

  // Initialize Mojo IPC.
  mojo::core::Init();
  ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
      base::ThreadTaskRunnerHandle::Get() /* io_thread_task_runner */,
      mojo::core::ScopedIPCSupport::ShutdownPolicy::
          CLEAN /* blocking shutdown */);

  return EX_OK;
}

void OcrDaemon::RegisterDBusObjectsAsync(
    brillo::dbus_utils::AsyncEventSequencer* sequencer) {
  DCHECK(!dbus_object_);
  dbus_object_ = std::make_unique<brillo::dbus_utils::DBusObject>(
      nullptr /* object_manager */, bus_, dbus::ObjectPath(kOcrServicePath));
  brillo::dbus_utils::DBusInterface* dbus_interface =
      dbus_object_->AddOrGetInterface(kOcrServiceInterface);
  DCHECK(dbus_interface);
  dbus_interface->AddSimpleMethodHandler(kBootstrapMojoConnectionMethod,
                                         base::Unretained(this),
                                         &OcrDaemon::BootstrapMojoConnection);
  dbus_object_->RegisterAsync(sequencer->GetHandler(
      "Failed to register D-Bus object" /* descriptive_message */,
      true /* failure_is_fatal */));
}

std::string OcrDaemon::BootstrapMojoConnection(const base::ScopedFD& mojo_fd,
                                               bool should_accept_invitation) {
  VLOG(1) << "Received BootstrapMojoConnection D-Bus request";

  if (!mojo_fd.is_valid()) {
    constexpr char kInvalidFileDescriptorError[] =
        "ScopedFD extracted from D-Bus call was invalid (i.e. empty)";
    LOG(ERROR) << kInvalidFileDescriptorError;
    return kInvalidFileDescriptorError;
  }

  // We need a file descriptor that stays alive after the current method
  // finishes, but libbrillo's D-Bus wrappers currently don't support passing
  // base::ScopedFD by value.
  base::ScopedFD mojo_fd_copy(HANDLE_EINTR(dup(mojo_fd.get())));
  if (!mojo_fd_copy.is_valid()) {
    constexpr char kFailedDuplicationError[] =
        "Failed to duplicate the Mojo file descriptor";
    PLOG(ERROR) << kFailedDuplicationError;
    return kFailedDuplicationError;
  }

  if (!base::SetCloseOnExec(mojo_fd_copy.get())) {
    constexpr char kFailedSettingFdCloexec[] =
        "Failed to set FD_CLOEXEC on Mojo file descriptor";
    PLOG(ERROR) << kFailedSettingFdCloexec;
    return kFailedSettingFdCloexec;
  }

  std::string token;
  mojo::ScopedMessagePipeHandle mojo_message_pipe;
  if (should_accept_invitation) {
    if (mojo_service_bind_attempted_) {
      // This should not normally be triggered, since the other endpoint - the
      // browser process - should bootstrap the Mojo connection only once, and
      // when that process is killed the Mojo shutdown notification should have
      // been received earlier. But handle this case to be on the safe side.
      // After we restart, the browser process is expected to invoke the
      // bootstrapping again.
      LOG(ERROR) << "Shutting down due to repeated Mojo bootstrap requests";
      ocr_service_impl_.reset();
      Quit();
      return "";
    }

    // Connect to Mojo in the requesting process.
    mojo::IncomingInvitation invitation =
        mojo::IncomingInvitation::Accept(mojo::PlatformChannelEndpoint(
            mojo::PlatformHandle(std::move(mojo_fd_copy))));
    mojo_message_pipe =
        invitation.ExtractMessagePipe(kBootstrapMojoConnectionChannelToken);
    mojo_service_bind_attempted_ = true;
  } else {
    // Create a unique token which will allow the requesting process to connect
    // to us via Mojo.
    mojo::OutgoingInvitation invitation;
    token = base::UnguessableToken::Create().ToString();
    mojo_message_pipe = invitation.AttachMessagePipe(token);
    mojo::OutgoingInvitation::Send(
        std::move(invitation), base::kNullProcessHandle,
        mojo::PlatformChannelEndpoint(
            mojo::PlatformHandle(std::move(mojo_fd_copy))));
  }
  ocr_service_impl_->AddReceiver(
      mojo::PendingReceiver<
          chromeos::ocr::mojom::OpticalCharacterRecognitionService>(
          std::move(mojo_message_pipe)),
      should_accept_invitation);
  VLOG(1) << "Successfully bootstrapped Mojo connection";
  return token;
}

void OcrDaemon::OnDisconnect(bool should_quit) {
  if (should_quit) {
    LOG(ERROR) << "OcrDaemon lost Mojo connection to the browser; quitting.";
    ocr_service_impl_.reset();
    Quit();
  }
}

}  // namespace ocr
