// Copyright 2018 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 "arc/vm/mojo_proxy/server_proxy.h"

#include <poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/posix/unix_domain_socket.h>
#include <base/stl_util.h>
#include <base/synchronization/waitable_event.h>
#include <base/threading/thread_task_runner_handle.h>
#include <brillo/userdb_utils.h>

#include "arc/vm/mojo_proxy/file_descriptor_util.h"
#include "arc/vm/mojo_proxy/message.pb.h"
#include "arc/vm/mojo_proxy/mojo_proxy.h"
#include "arc/vm/mojo_proxy/proxy_file_system.h"

namespace arc {
namespace {

// Crosvm connects to this socket when creating a new virtwl context.
constexpr char kVirtwlSocketPath[] = "/run/arcvm/mojo/mojo-proxy.sock";

// Sets up a socket to accept virtwl connections.
base::ScopedFD SetupVirtwlSocket() {
  // Delete the socket created by a previous run if any.
  if (!base::DeleteFile(base::FilePath(kVirtwlSocketPath))) {
    PLOG(ERROR) << "DeleteFile() failed " << kVirtwlSocketPath;
    return {};
  }
  // Bind a socket to the path.
  base::ScopedFD sock(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
  if (!sock.is_valid()) {
    PLOG(ERROR) << "socket() failed";
    return {};
  }
  struct sockaddr_un unix_addr = {};
  unix_addr.sun_family = AF_UNIX;
  strncpy(unix_addr.sun_path, kVirtwlSocketPath, sizeof(unix_addr.sun_path));
  if (bind(sock.get(), reinterpret_cast<const sockaddr*>(&unix_addr),
           sizeof(unix_addr)) < 0) {
    PLOG(ERROR) << "bind failed " << kVirtwlSocketPath;
    return {};
  }
  // Make it accessible to crosvm.
  uid_t uid = 0;
  gid_t gid = 0;
  if (!brillo::userdb::GetUserInfo("crosvm", &uid, &gid)) {
    LOG(ERROR) << "Failed to get crosvm user info.";
    return {};
  }
  if (lchown(kVirtwlSocketPath, uid, gid) != 0) {
    PLOG(ERROR) << "lchown failed";
    return {};
  }
  // Start listening on the socket.
  if (listen(sock.get(), SOMAXCONN) < 0) {
    PLOG(ERROR) << "listen failed";
    return {};
  }
  return sock;
}

}  // namespace

ServerProxy::ServerProxy(
    scoped_refptr<base::TaskRunner> proxy_file_system_task_runner,
    const base::FilePath& proxy_file_system_mount_path,
    base::OnceClosure quit_closure)
    : proxy_file_system_task_runner_(proxy_file_system_task_runner),
      proxy_file_system_(this,
                         base::ThreadTaskRunnerHandle::Get(),
                         proxy_file_system_mount_path),
      quit_closure_(std::move(quit_closure)) {}

ServerProxy::~ServerProxy() = default;

bool ServerProxy::Initialize() {
  // Initialize ProxyFileSystem.
  base::WaitableEvent file_system_initialized(
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  bool result = false;
  proxy_file_system_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          [](ProxyFileSystem* proxy_file_system,
             base::WaitableEvent* file_system_initialized, bool* result) {
            *result = proxy_file_system->Init();
            file_system_initialized->Signal();
          },
          &proxy_file_system_, &file_system_initialized, &result));
  file_system_initialized.Wait();
  if (!result) {
    LOG(ERROR) << "Failed to initialize ProxyFileSystem.";
    return false;
  }

  // Start listening on mojo-proxy.sock.
  virtwl_socket_ = SetupVirtwlSocket();
  if (!virtwl_socket_.is_valid()) {
    LOG(ERROR) << "Failed to set up virtwl socket.";
    return false;
  }

  // Accept connection from crosvm.
  // When the guest proxy creates a new virtwl context whose name is "mojo",
  // crosvm handles it by associating the virtwl context with mojo-proxy.sock.
  LOG(INFO) << "Accepting guest virtwl connection...";
  virtwl_context_ = AcceptSocket(virtwl_socket_.get());
  if (!virtwl_context_.is_valid()) {
    LOG(ERROR) << "Failed to accept virtwl connection";
    return false;
  }

  // Use virtwl to receive messages from guest.
  LOG(INFO) << "Using virtwl to receive messages.";
  message_stream_ = std::make_unique<MessageStream>(std::move(virtwl_context_));

  mojo_proxy_ = std::make_unique<MojoProxy>(this);
  LOG(INFO) << "ServerProxy has started to work.";
  return true;
}

base::ScopedFD ServerProxy::CreateProxiedRegularFile(int64_t handle,
                                                     int32_t flags) {
  // Create a file descriptor which is handled by |proxy_file_system_|.
  return proxy_file_system_.RegisterHandle(handle, flags);
}

bool ServerProxy::SendMessage(const arc_proxy::MojoMessage& message,
                              const std::vector<base::ScopedFD>& fds) {
  if (!fds.empty()) {
    LOG(ERROR) << "It's not allowed to send FDs from host to guest.";
    return false;
  }
  return message_stream_->Write(message);
}

bool ServerProxy::ReceiveMessage(arc_proxy::MojoMessage* message,
                                 std::vector<base::ScopedFD>* fds) {
  return message_stream_->Read(message, fds);
}

void ServerProxy::OnStopped() {
  std::move(quit_closure_).Run();
}

void ServerProxy::Pread(int64_t handle,
                        uint64_t count,
                        uint64_t offset,
                        PreadCallback callback) {
  mojo_proxy_->Pread(handle, count, offset, std::move(callback));
}

void ServerProxy::Pwrite(int64_t handle,
                         std::string blob,
                         uint64_t offset,
                         PwriteCallback callback) {
  mojo_proxy_->Pwrite(handle, std::move(blob), offset, std::move(callback));
}

void ServerProxy::Close(int64_t handle) {
  mojo_proxy_->Close(handle);
}

void ServerProxy::Fstat(int64_t handle, FstatCallback callback) {
  mojo_proxy_->Fstat(handle, std::move(callback));
}

}  // namespace arc
