// 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 <sys/types.h>
#include <unistd.h>

#include <tuple>
#include <utility>
#include <vector>

#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/object_proxy.h>
#include <vm_concierge/proto_bindings/concierge_service.pb.h>

#include "arc/vm/forward-pstore/service.h"
#include "vm_tools/common/naming.h"
#include "vm_tools/common/pstore.h"

namespace arc {
namespace {

constexpr char kArcVmName[] = "arcvm";
constexpr char kArcVmDir[] = "/run/arcvm";
constexpr char kPstoreSourceName[] = "arcvm.pstore";
constexpr char kCryptohomeRoot[] = "/run/daemon-store/crosvm";
constexpr char kPstoreExtension[] = ".pstore";
constexpr base::TimeDelta kReadDelay = base::TimeDelta::FromSeconds(5);

base::FilePath GetPstoreDest(const std::string& owner_id) {
  return base::FilePath(kCryptohomeRoot)
      .Append(owner_id)
      .Append(vm_tools::GetEncodedName(kArcVmName))
      .AddExtension(kPstoreExtension);
}

}  // namespace

Service::Service(base::Closure quit_closure)
    : quit_closure_(quit_closure), weak_ptr_factory_(this) {}

Service::~Service() = default;

void Service::Start() {
  // Connect to dbus.
  dbus::Bus::Options opts;
  opts.bus_type = dbus::Bus::SYSTEM;
  bus_ = new dbus::Bus(std::move(opts));
  if (!bus_->Connect())
    LOG(FATAL) << "Failed to connect to system bus";

  // Subscribe to concierge signals
  auto concierge_proxy = bus_->GetObjectProxy(
      vm_tools::concierge::kVmConciergeServiceName,
      dbus::ObjectPath(vm_tools::concierge::kVmConciergeServicePath));
  if (!concierge_proxy)
    LOG(FATAL) << "Failed to get Concierge proxy";

  concierge_proxy->ConnectToSignal(
      vm_tools::concierge::kVmConciergeInterface,
      vm_tools::concierge::kVmIdChangedSignal,
      base::BindRepeating(&Service::OnVmIdChangedSignal,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&Service::OnSignalConnected,
                     weak_ptr_factory_.GetWeakPtr()));
  concierge_proxy->ConnectToSignal(
      vm_tools::concierge::kVmConciergeInterface,
      vm_tools::concierge::kVmStoppedSignal,
      base::BindRepeating(&Service::OnVmStoppedSignal,
                          weak_ptr_factory_.GetWeakPtr()),
      base::BindOnce(&Service::OnSignalConnected,
                     weak_ptr_factory_.GetWeakPtr()));
}

void Service::OnSignalConnected(const std::string& interface_name,
                                const std::string& signal_name,
                                bool is_connected) {
  if (!is_connected)
    LOG(FATAL) << "Failed to connect to signal: " << signal_name;
  VLOG(1) << "Connected to " << signal_name;
}

void Service::OnVmIdChangedSignal(dbus::Signal* signal) {
  DCHECK_EQ(signal->GetInterface(), vm_tools::concierge::kVmConciergeInterface);
  DCHECK_EQ(signal->GetMember(), vm_tools::concierge::kVmIdChangedSignal);

  vm_tools::concierge::VmIdChangedSignal vm_changed_signal;
  dbus::MessageReader reader(signal);
  if (!reader.PopArrayOfBytesAsProto(&vm_changed_signal)) {
    LOG(ERROR) << "Failed to parse proto from DBus Signal";
    return;
  }

  if (vm_changed_signal.name() != kArcVmName) {
    VLOG(1) << "Ignoring VmIdChangedSignal from non-ARC VM: "
            << vm_changed_signal.name();
    return;
  }

  VLOG(1) << "Received VmIdChangedSignal for ARCVM";
  ForwardPstore(vm_changed_signal.owner_id());
  return;
}

void Service::OnVmStoppedSignal(dbus::Signal* signal) {
  DCHECK_EQ(signal->GetInterface(), vm_tools::concierge::kVmConciergeInterface);
  DCHECK_EQ(signal->GetMember(), vm_tools::concierge::kVmStoppedSignal);

  vm_tools::concierge::VmStoppedSignal vm_stopped_signal;
  dbus::MessageReader reader(signal);
  if (!reader.PopArrayOfBytesAsProto(&vm_stopped_signal)) {
    PLOG(ERROR) << "Failed to parse proto from DBus Signal";
    return;
  }

  if (vm_stopped_signal.name() != kArcVmName) {
    LOG(INFO) << "Ignoring VmStoppedSignal from non-ARC VM: "
              << vm_stopped_signal.name();
    return;
  }

  // ForwardContents() one last time to get final dmesg output.
  ForwardContents(vm_stopped_signal.owner_id());

  // Stop timer and close fds.
  timer_.Stop();
  pstore_fd_.reset();
  root_fd_.reset();
  dest_fd_.reset();
}

void Service::ForwardPstore(const std::string& owner_id) {
  DCHECK(!pstore_fd_.is_valid());

  brillo::SafeFD root_fd;
  brillo::SafeFD arcvm_dir_fd;
  brillo::SafeFD pstore_fd;
  brillo::SafeFD::Error err;
  std::tie(root_fd, err) = brillo::SafeFD::Root();
  if (brillo::SafeFD::IsError(err) || !root_fd.is_valid()) {
    LOG(ERROR) << "Failed to open root fd, error:" << static_cast<int>(err);
    return;
  }
  std::tie(arcvm_dir_fd, err) =
      root_fd.OpenExistingDir(base::FilePath(kArcVmDir));
  if (brillo::SafeFD::IsError(err) || !arcvm_dir_fd.is_valid()) {
    LOG(ERROR) << "Failed to open " << kArcVmDir
               << ", error:" << static_cast<int>(err);
    return;
  }
  std::tie(pstore_fd, err) =
      arcvm_dir_fd.OpenExistingFile(base::FilePath(kPstoreSourceName));
  if (brillo::SafeFD::IsError(err) || !arcvm_dir_fd.is_valid()) {
    // On aarch64 platforms, crosvm does not create a pstore file. Log a warning
    // and return.
    VLOG(1) << "Failed to open " << kArcVmDir << "/" << kPstoreSourceName
            << ", error:" << static_cast<int>(err);
    return;
  }

  // Unlink pstore from /run/arcvm location.
  err = arcvm_dir_fd.Unlink(kPstoreSourceName);
  if (brillo::SafeFD::IsError(err))
    LOG(ERROR) << "Failed to unlink " << kPstoreSourceName
               << ", error:" << static_cast<int>(err);

  // Start forwarding the contents to cryptohome location.
  root_fd_ = std::move(root_fd);
  pstore_fd_ = std::move(pstore_fd);
  timer_.Start(FROM_HERE, kReadDelay,
               base::BindRepeating(&Service::ForwardContents,
                                   weak_ptr_factory_.GetWeakPtr(), owner_id));
  ForwardContents(owner_id);
}

void Service::ForwardContents(const std::string& owner_id) {
  if (!pstore_fd_.is_valid()) {
    LOG(ERROR) << "Pstore source fd is invalid";
    return;
  }

  // Seek to beginning of file before reading.
  if (lseek(pstore_fd_.get(), 0, SEEK_SET) != 0) {
    PLOG(ERROR) << "Cannot seek to beginning of pstore file";
    return;
  }
  // Read pstore.
  std::vector<char> content;
  brillo::SafeFD::Error err;
  std::tie(content, err) = pstore_fd_.ReadContents(vm_tools::kArcVmPstoreSize);
  if (brillo::SafeFD::IsError(err)) {
    LOG(ERROR) << "Failed to read pstore source fd, error:"
               << static_cast<int>(err);
    return;
  }

  // Write to cryptohome path.
  if (!dest_fd_.is_valid()) {
    base::FilePath dest = GetPstoreDest(owner_id);
    std::tie(dest_fd_, err) = root_fd_.MakeFile(dest, 0700, getuid(), getgid(),
                                                O_WRONLY | O_CLOEXEC | O_TRUNC);
    if (brillo::SafeFD::IsError(err) || !dest_fd_.is_valid()) {
      LOG(ERROR) << "Failed to open destination fd " << dest
                 << ", error:" << static_cast<int>(err);
      return;
    }
  }
  // Seek to beginning of file before writing.
  if (lseek(dest_fd_.get(), 0, SEEK_SET) != 0) {
    PLOG(ERROR) << "Cannot seek to beginning of pstore destination";
    return;
  }
  err = dest_fd_.Write(content.data(), content.size());
  if (brillo::SafeFD::IsError(err))
    LOG(ERROR) << "Failed to write to pstore destination, error:"
               << static_cast<int>(err);
}
}  // namespace arc
