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

#include <sysexits.h>

#include <string>
#include <utility>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <mojo/core/embedder/embedder.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

namespace cups_proxy {

namespace {

constexpr char kCupsProxySocketPath[] = "/run/cups_proxy/cups.sock";

base::ScopedFD InitSocket() {
  base::ScopedFD fd(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
  if (!fd.is_valid()) {
    PLOG(ERROR) << "Failed to create socket";
    return {};
  }

  struct sockaddr_un unix_addr = {};
  base::FilePath socket_path(kCupsProxySocketPath);
  std::string socket_name = socket_path.value();

  unix_addr.sun_family = AF_UNIX;
  CHECK(socket_name.size() < sizeof(unix_addr.sun_path));
  strncpy(unix_addr.sun_path, socket_name.c_str(), socket_name.size());
  size_t unix_addr_len =
      offsetof(struct sockaddr_un, sun_path) + socket_name.size();

  // Delete any old FS instances.
  if (unlink(socket_name.c_str()) < 0 && errno != ENOENT) {
    PLOG(ERROR) << "unlink " << socket_name;
    return {};
  }

  // Bind the socket.
  if (bind(fd.get(), reinterpret_cast<const sockaddr*>(&unix_addr),
           unix_addr_len) < 0) {
    PLOG(ERROR) << "bind " << socket_path.value();
    return {};
  }

  // Sets the correct socket permissions.
  if (chmod(socket_name.c_str(), 0660) < 0) {
    PLOG(ERROR) << "Failed to set permissions";
    unlink(socket_name.c_str());
    return {};
  }

  // Start listening on the socket.
  if (listen(fd.get(), SOMAXCONN) < 0) {
    PLOG(ERROR) << "listen " << socket_path.value();
    unlink(socket_name.c_str());
    return {};
  }

  return fd;
}

}  // namespace

Daemon::Daemon() : weak_ptr_factory_(this) {}

Daemon::~Daemon() {}

int Daemon::OnInit() {
  int exit_code = DBusDaemon::OnInit();
  if (exit_code != EX_OK)
    return exit_code;

  mojo::core::Init();
  ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
      base::ThreadTaskRunnerHandle::Get(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);

  CHECK(mojo_handler_.StartThread());

  InitDBus();

  base::ScopedFD listen_fd = InitSocket();
  if (!listen_fd.is_valid()) {
    LOG(ERROR) << "Error initializing unix listen socket.";
    return EX_UNAVAILABLE;
  }

  mhd_daemon_ = StartMHDDaemon(std::move(listen_fd), &mojo_handler_);
  if (!mhd_daemon_) {
    LOG(ERROR) << "Error initializing MHD daemon.";
    return EX_UNAVAILABLE;
  }

  return EX_OK;
}

void Daemon::InitDBus() {
  LOG(INFO) << "Registering as handler for CupsProxyDaemon in D-Bus ...";

  // Get or create the ExportedObject for the CupsProxyDaemon
  dbus::ExportedObject* const cups_proxy_exported_object =
      bus_->GetExportedObject(dbus::ObjectPath(printing::kCupsProxyDaemonPath));
  CHECK(cups_proxy_exported_object);

  // Register a handler of the BootstrapMojoConnection method.
  CHECK(cups_proxy_exported_object->ExportMethodAndBlock(
      printing::kCupsProxyDaemonInterface,
      printing::kBootstrapMojoConnectionMethod,
      base::Bind(&Daemon::BootstrapMojoConnection,
                 weak_ptr_factory_.GetWeakPtr())));

  // Take ownership of the CupsProxy service.
  CHECK(bus_->RequestOwnershipAndBlock(printing::kCupsProxyDaemonName,
                                       dbus::Bus::REQUIRE_PRIMARY));
}

void Daemon::BootstrapMojoConnection(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender response_sender) {
  if (mojo_handler_.IsInitialized()) {
    LOG(ERROR) << "CupsProxyService already initialized";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_FAILED, "Bootstrap already completed"));
    return;
  }

  base::ScopedFD file_handle;
  dbus::MessageReader reader(method_call);

  if (!reader.PopFileDescriptor(&file_handle)) {
    LOG(ERROR) << "Couldn't extract file descriptor from D-Bus call";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_INVALID_ARGS, "Expected file descriptor"));
    return;
  }

  if (!file_handle.is_valid()) {
    LOG(ERROR) << "ScopedFD extracted from D-Bus call was invalid (i.e. empty)";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_INVALID_ARGS,
            "Invalid (empty) file descriptor"));
    return;
  }

  if (!base::SetCloseOnExec(file_handle.get())) {
    PLOG(ERROR) << "Failed setting FD_CLOEXEC on file descriptor";
    std::move(response_sender)
        .Run(dbus::ErrorResponse::FromMethodCall(
            method_call, DBUS_ERROR_FAILED,
            "Failed setting FD_CLOEXEC on file descriptor"));
    return;
  }

  // Connect to mojo in the requesting process.
  mojo_handler_.SetupMojoPipe(
      std::move(file_handle),
      base::Bind(&Daemon::OnConnectionError, base::Unretained(this)));

  // Send success response.
  std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
}

void Daemon::OnConnectionError() {
  // Die upon Mojo error. Reconnection can occur when the daemon is restarted.
  // (A future Mojo API may enable Mojo re-bootstrap without a process restart.)
  LOG(ERROR) << "CupsProxyDaemon MojoConnectionError; quitting.";
  Quit();
}

}  // namespace cups_proxy
