// 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 "vm_tools/cicerone/virtual_machine.h"

#include <arpa/inet.h>
#include <inttypes.h>

#include <algorithm>
#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/check.h>
#include <base/guid.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/stringprintf.h>
#include <google/protobuf/repeated_field.h>
#include <grpcpp/grpcpp.h>
#include <vm_cicerone/proto_bindings/cicerone_service.pb.h>
#include <vm_protos/proto_bindings/container_guest.grpc.pb.h>
#include <chromeos/constants/vm_tools.h>

using std::string;

namespace vm_tools {
namespace cicerone {
namespace {

// Default name to use for a container.
constexpr char kDefaultContainerName[] = "penguin";

// How long to wait before timing out on regular RPCs.
constexpr int64_t kDefaultTimeoutSeconds = 60;

// How long to wait while doing more complex operations like starting or
// creating a container.
constexpr int64_t kLongOperationTimeoutSeconds = 120;

VirtualMachine::VmType DetermineTypeFromCidAndToken(uint32_t cid,
                                                    const std::string& token) {
  // PluginVm does not have a CID
  if (cid == 0)
    return VirtualMachine::VmType::ApplicationList_VmType_PLUGIN_VM;
  // Termina hosts containers, so it does not have a VM token.
  if (token.empty())
    return VirtualMachine::VmType::ApplicationList_VmType_TERMINA;
  return VirtualMachine::VmType::ApplicationList_VmType_BOREALIS;
}

}  // namespace

VirtualMachine::VirtualMachine(uint32_t cid, pid_t pid, std::string vm_token)
    : vsock_cid_(cid),
      pid_(pid),
      vm_token_(std::move(vm_token)),
      vm_type_(DetermineTypeFromCidAndToken(cid, vm_token_)),
      using_mock_tremplin_stub_(false),
      weak_ptr_factory_(this) {
  // CID-less VMs must also be containerless.
  DCHECK(vsock_cid_ != 0 || IsContainerless());
  if (IsContainerless()) {
    // This is a containerless VM, so create one container for this VM that uses
    // the same token as the VM itself.
    pending_containers_[vm_token_] = std::make_unique<Container>(
        kDefaultContainerName, vm_token_, weak_ptr_factory_.GetWeakPtr());
  }
}

VirtualMachine::~VirtualMachine() = default;

VirtualMachine::VmType VirtualMachine::GetType() const {
  return vm_type_;
}

bool VirtualMachine::IsContainerless() const {
  // Termina runs containers, the others do not.
  return GetType() != VmType::ApplicationList_VmType_TERMINA;
}

bool VirtualMachine::ConnectTremplin() {
  // Tremplin manages LXD/containers, so containerless VMs dont use it.
  if (IsContainerless())
    return false;
  if (!using_mock_tremplin_stub_) {
    std::string tremplin_address =
        base::StringPrintf("vsock:%u:%u", vsock_cid_, kTremplinPort);
    tremplin_stub_ = std::make_unique<vm_tools::tremplin::Tremplin::Stub>(
        grpc::CreateChannel(tremplin_address,
                            grpc::InsecureChannelCredentials()));
  }
  return tremplin_stub_ != nullptr;
}

void VirtualMachine::SetTremplinStubForTesting(
    std::unique_ptr<vm_tools::tremplin::Tremplin::StubInterface>
        mock_tremplin_stub) {
  CHECK(using_mock_tremplin_stub_ || !tremplin_stub_)
      << "Calling SetTremplinStubForTesting too late";
  using_mock_tremplin_stub_ = true;
  tremplin_stub_ = std::move(mock_tremplin_stub);
}

bool VirtualMachine::SetTimezone(
    const std::string& timezone_name,
    const std::string& posix_tz_string,
    const std::vector<std::string>& container_names,
    VirtualMachine::SetTimezoneResults* out_results,
    std::string* out_error) {
  DCHECK(out_results);
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return false;
  }
  LOG(INFO) << "Setting timezone to: " << timezone_name;

  vm_tools::tremplin::SetTimezoneRequest request;
  vm_tools::tremplin::SetTimezoneResponse response;

  request.set_timezone_name(timezone_name);
  request.set_posix_tz_string(posix_tz_string);
  for (const std::string& name : container_names)
    request.add_container_names(name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status = tremplin_stub_->SetTimezone(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "SetTimezone RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return false;
  }

  int failure_count = response.failure_reasons_size();
  if (failure_count != 0) {
    LOG(ERROR) << "Failed to set timezone for " << failure_count
               << " containers";
  }
  out_results->failure_reasons.clear();
  for (int i = 0; i < failure_count; i++) {
    out_results->failure_reasons.push_back(response.failure_reasons(i));
  }

  out_results->successes = response.successes();
  return true;
}

bool VirtualMachine::RegisterContainer(const std::string& container_token,
                                       const uint32_t garcon_vsock_port,
                                       const std::string& container_ip) {
  // The token will be in the pending map if this is the first start of the
  // container. It will be in the main map if this is from a crash/restart of
  // the garcon process in the container.
  auto pending_iter = pending_containers_.find(container_token);
  if (pending_iter != pending_containers_.end()) {
    containers_[pending_iter->first] = std::move(pending_iter->second);
    pending_containers_.erase(pending_iter);
  } else {
    string container_name = GetContainerNameForToken(container_token);
    if (container_name.empty()) {
      return false;
    }
  }

  auto iter = containers_.find(container_token);
  std::string garcon_addr;
  if (GetType() == VmType::ApplicationList_VmType_PLUGIN_VM) {
    garcon_addr = base::StringPrintf("unix:///run/vm_cicerone/client/%s.sock",
                                     container_token.c_str());
  } else if (garcon_vsock_port != 0) {
    garcon_addr = base::StringPrintf("vsock:%" PRIu32 ":%" PRIu32, vsock_cid_,
                                     garcon_vsock_port);
  } else {
    garcon_addr = base::StringPrintf("%s:%d", container_ip.c_str(),
                                     vm_tools::kGarconPort);
  }

  iter->second->ConnectToGarcon(garcon_addr);

  return true;
}

bool VirtualMachine::UnregisterContainer(const std::string& container_token) {
  auto iter = containers_.find(container_token);
  if (iter == containers_.end()) {
    return false;
  }
  containers_.erase(iter);
  return true;
}

std::string VirtualMachine::GenerateContainerToken(
    const std::string& container_name) {
  if (IsContainerless())
    return "";
  std::string token = base::GenerateGUID();
  pending_containers_[token] = std::make_unique<Container>(
      container_name, token, weak_ptr_factory_.GetWeakPtr());
  return token;
}

void VirtualMachine::CreateContainerWithTokenForTesting(
    const std::string& container_name, const std::string& container_token) {
  pending_containers_[container_token] = std::make_unique<Container>(
      container_name, container_token, weak_ptr_factory_.GetWeakPtr());
}

std::string VirtualMachine::GetContainerNameForToken(
    const std::string& container_token) {
  auto iter = containers_.find(container_token);
  if (iter == containers_.end()) {
    return "";
  }
  return iter->second->name();
}

Container* VirtualMachine::GetContainerForToken(
    const std::string& container_token) {
  auto iter = containers_.find(container_token);
  if (iter == containers_.end()) {
    return nullptr;
  }

  return iter->second.get();
}

Container* VirtualMachine::GetPendingContainerForToken(
    const std::string& container_token) {
  auto iter = pending_containers_.find(container_token);
  if (iter == pending_containers_.end()) {
    return nullptr;
  }

  return iter->second.get();
}

Container* VirtualMachine::GetContainerForName(
    const std::string& container_name) {
  for (auto iter = containers_.begin(); iter != containers_.end(); ++iter) {
    if (iter->second->name() == container_name) {
      return iter->second.get();
    }
  }
  return nullptr;
}

const OsRelease* VirtualMachine::GetOsReleaseForContainer(
    const std::string& container_name) const {
  auto iter = container_os_releases_.find(container_name);
  if (iter == container_os_releases_.end()) {
    return nullptr;
  }

  return &iter->second;
}

void VirtualMachine::SetOsReleaseForTesting(const std::string& container_name,
                                            const OsRelease& os_release) {
  container_os_releases_[container_name] = os_release;
}

std::vector<std::string> VirtualMachine::GetContainerNames() {
  std::vector<std::string> retval;
  for (auto& container_entry : containers_) {
    retval.emplace_back(container_entry.second->name());
  }
  return retval;
}

VirtualMachine::CreateLxdContainerStatus VirtualMachine::CreateLxdContainer(
    const std::string& container_name,
    const std::string& image_server,
    const std::string& image_alias,
    const std::string& rootfs_path,
    const std::string& metadata_path,
    std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::CreateLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::CreateContainerRequest request;
  vm_tools::tremplin::CreateContainerResponse response;

  request.set_container_name(container_name);
  request.set_image_server(image_server);
  request.set_image_alias(image_alias);
  request.set_rootfs_path(rootfs_path);
  request.set_metadata_path(metadata_path);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kLongOperationTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->CreateContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "CreateContainer RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::CreateLxdContainerStatus::FAILED;
  }

  if (response.status() != tremplin::CreateContainerResponse::CREATING &&
      response.status() != tremplin::CreateContainerResponse::EXISTS) {
    LOG(ERROR) << "Failed to create LXD container: "
               << response.failure_reason();
    out_error->assign(response.failure_reason());
    return VirtualMachine::CreateLxdContainerStatus::FAILED;
  }

  if (response.status() == tremplin::CreateContainerResponse::EXISTS) {
    return VirtualMachine::CreateLxdContainerStatus::EXISTS;
  }

  return VirtualMachine::CreateLxdContainerStatus::CREATING;
}

VirtualMachine::DeleteLxdContainerStatus VirtualMachine::DeleteLxdContainer(
    const std::string& container_name, std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::DeleteLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::DeleteContainerRequest request;
  vm_tools::tremplin::DeleteContainerResponse response;

  request.set_container_name(container_name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->DeleteContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "DeleteContainer RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::DeleteLxdContainerStatus::FAILED;
  }

  switch (response.status()) {
    case tremplin::DeleteContainerResponse::DELETING:
      return VirtualMachine::DeleteLxdContainerStatus::DELETING;
    case tremplin::DeleteContainerResponse::DOES_NOT_EXIST:
      return VirtualMachine::DeleteLxdContainerStatus::DOES_NOT_EXIST;

    case tremplin::DeleteContainerResponse::UNKNOWN:
    case tremplin::DeleteContainerResponse::FAILED:
      LOG(ERROR) << "Failed to delete LXD container: "
                 << response.failure_reason();
      out_error->assign(response.failure_reason());
      return VirtualMachine::DeleteLxdContainerStatus::FAILED;

    default:
      LOG(ERROR) << "Unknown response received: " << response.status() << " "
                 << response.failure_reason();
      out_error->assign(response.failure_reason());
      return VirtualMachine::DeleteLxdContainerStatus::UNKNOWN;
  }
}

VirtualMachine::StartLxdContainerStatus VirtualMachine::StartLxdContainer(
    const std::string& container_name,
    const std::string& container_private_key,
    const std::string& host_public_key,
    const std::string& token,
    tremplin::StartContainerRequest::PrivilegeLevel privilege_level,
    std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::StartLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::StartContainerRequest request;
  vm_tools::tremplin::StartContainerResponse response;

  request.set_container_name(container_name);
  request.set_container_private_key(container_private_key);
  request.set_host_public_key(host_public_key);
  request.set_token(token);
  request.set_privilege_level(privilege_level);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kLongOperationTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->StartContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "StartContainer RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::StartLxdContainerStatus::FAILED;
  }

  if (response.status() != tremplin::StartContainerResponse::RUNNING &&
      response.status() != tremplin::StartContainerResponse::FAILED) {
    // Set the os_release on the container. This information is known by
    // tremplin even if the container hasn't started fully. Note also that
    // Tremplin's version of OsRelease is not the same type as cicerone's, even
    // though they currently have the same fields.
    OsRelease os_release;
    os_release.set_pretty_name(response.os_release().pretty_name());
    os_release.set_name(response.os_release().name());
    os_release.set_version(response.os_release().version());
    os_release.set_version_id(response.os_release().version_id());
    os_release.set_id(response.os_release().id());
    // We don't use emplace() here because it doesn't replace existing values.
    container_os_releases_[container_name] = os_release;
  }

  switch (response.status()) {
    case tremplin::StartContainerResponse::STARTING:
      return VirtualMachine::StartLxdContainerStatus::STARTING;
    case tremplin::StartContainerResponse::STARTED:
      return VirtualMachine::StartLxdContainerStatus::STARTED;
    case tremplin::StartContainerResponse::REMAPPING:
      return VirtualMachine::StartLxdContainerStatus::REMAPPING;
    case tremplin::StartContainerResponse::RUNNING:
      return VirtualMachine::StartLxdContainerStatus::RUNNING;
    case tremplin::StartContainerResponse::FAILED:
      LOG(ERROR) << "Failed to start LXD container: "
                 << response.failure_reason();
      out_error->assign(response.failure_reason());
      return VirtualMachine::StartLxdContainerStatus::FAILED;
    default:
      return VirtualMachine::StartLxdContainerStatus::UNKNOWN;
  }
}

VirtualMachine::GetLxdContainerUsernameStatus
VirtualMachine::GetLxdContainerUsername(const std::string& container_name,
                                        std::string* out_username,
                                        std::string* out_homedir,
                                        std::string* out_error) {
  DCHECK(out_username);
  DCHECK(out_homedir);
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::GetLxdContainerUsernameStatus::FAILED;
  }

  vm_tools::tremplin::GetContainerUsernameRequest request;
  vm_tools::tremplin::GetContainerUsernameResponse response;

  request.set_container_name(container_name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->GetContainerUsername(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "GetContainerUsername RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::GetLxdContainerUsernameStatus::FAILED;
  }

  out_error->assign(response.failure_reason());
  out_username->assign(response.username());
  out_homedir->assign(response.homedir());

  switch (response.status()) {
    case tremplin::GetContainerUsernameResponse::UNKNOWN:
      return VirtualMachine::GetLxdContainerUsernameStatus::UNKNOWN;
    case tremplin::GetContainerUsernameResponse::SUCCESS:
      return VirtualMachine::GetLxdContainerUsernameStatus::SUCCESS;
    case tremplin::GetContainerUsernameResponse::CONTAINER_NOT_FOUND:
      return VirtualMachine::GetLxdContainerUsernameStatus::CONTAINER_NOT_FOUND;
    case tremplin::GetContainerUsernameResponse::CONTAINER_NOT_RUNNING:
      return VirtualMachine::GetLxdContainerUsernameStatus::
          CONTAINER_NOT_RUNNING;
    case tremplin::GetContainerUsernameResponse::USER_NOT_FOUND:
      return VirtualMachine::GetLxdContainerUsernameStatus::USER_NOT_FOUND;
    case tremplin::GetContainerUsernameResponse::FAILED:
      return VirtualMachine::GetLxdContainerUsernameStatus::FAILED;
    default:
      return VirtualMachine::GetLxdContainerUsernameStatus::UNKNOWN;
  }
}

VirtualMachine::SetUpLxdContainerUserStatus
VirtualMachine::SetUpLxdContainerUser(const std::string& container_name,
                                      const std::string& container_username,
                                      std::string* out_username,
                                      std::string* out_error) {
  DCHECK(out_username);
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::SetUpLxdContainerUserStatus::FAILED;
  }

  vm_tools::tremplin::SetUpUserRequest request;
  vm_tools::tremplin::SetUpUserResponse response;

  request.set_container_name(container_name);
  request.set_container_username(container_username);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status = tremplin_stub_->SetUpUser(&ctx, request, &response);
  out_username->assign(response.username());
  if (!status.ok()) {
    LOG(ERROR) << "SetUpUser RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::SetUpLxdContainerUserStatus::FAILED;
  }

  out_error->assign(response.failure_reason());
  switch (response.status()) {
    case tremplin::SetUpUserResponse::UNKNOWN:
      LOG(ERROR) << "Failed to set up user: " << response.failure_reason();
      return VirtualMachine::SetUpLxdContainerUserStatus::UNKNOWN;
    case tremplin::SetUpUserResponse::SUCCESS:
      return VirtualMachine::SetUpLxdContainerUserStatus::SUCCESS;
    case tremplin::SetUpUserResponse::EXISTS:
      return VirtualMachine::SetUpLxdContainerUserStatus::EXISTS;
    case tremplin::SetUpUserResponse::FAILED:
      LOG(ERROR) << "Failed to set up user: " << response.failure_reason();
      return VirtualMachine::SetUpLxdContainerUserStatus::FAILED;
    default:
      NOTREACHED();
      return VirtualMachine::SetUpLxdContainerUserStatus::FAILED;
  }
}

VirtualMachine::GetLxdContainerInfoStatus VirtualMachine::GetLxdContainerInfo(
    const std::string& container_name,
    VirtualMachine::LxdContainerInfo* out_info,
    std::string* out_error) {
  DCHECK(out_info);
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::GetLxdContainerInfoStatus::FAILED;
  }

  vm_tools::tremplin::GetContainerInfoRequest request;
  vm_tools::tremplin::GetContainerInfoResponse response;

  request.set_container_name(container_name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->GetContainerInfo(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "GetContainerInfo RPC failed: " << status.error_message();
    out_error->assign(status.error_message());
    return VirtualMachine::GetLxdContainerInfoStatus::FAILED;
  }

  out_info->ipv4_address = response.ipv4_address();
  out_error->assign(response.failure_reason());

  switch (response.status()) {
    case tremplin::GetContainerInfoResponse::RUNNING:
      return VirtualMachine::GetLxdContainerInfoStatus::RUNNING;
    case tremplin::GetContainerInfoResponse::STOPPED:
      return VirtualMachine::GetLxdContainerInfoStatus::STOPPED;
    case tremplin::GetContainerInfoResponse::NOT_FOUND:
      return VirtualMachine::GetLxdContainerInfoStatus::NOT_FOUND;
    default:
      return VirtualMachine::GetLxdContainerInfoStatus::UNKNOWN;
  }
}

VirtualMachine::ExportLxdContainerStatus VirtualMachine::ExportLxdContainer(
    const std::string& container_name,
    const std::string& export_path,
    std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::ExportLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::ExportContainerRequest request;
  vm_tools::tremplin::ExportContainerResponse response;

  request.set_container_name(container_name);
  request.set_export_path(export_path);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->ExportContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "ExportLxdContainer RPC failed: " << status.error_message()
               << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::ExportLxdContainerStatus::FAILED;
  }

  switch (response.status()) {
    case tremplin::ExportContainerResponse::EXPORTING:
      return VirtualMachine::ExportLxdContainerStatus::EXPORTING;
    case tremplin::ExportContainerResponse::FAILED:
      return VirtualMachine::ExportLxdContainerStatus::FAILED;
    default:
      return VirtualMachine::ExportLxdContainerStatus::UNKNOWN;
  }
}

VirtualMachine::CancelExportLxdContainerStatus
VirtualMachine::CancelExportLxdContainer(
    const std::string& in_progress_container_name, std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::CancelExportLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::CancelExportContainerRequest request;
  vm_tools::tremplin::CancelExportContainerResponse response;

  request.set_in_progress_container_name(in_progress_container_name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->CancelExportContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "CancelExportLxdContainer RPC failed: "
               << status.error_message() << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::CancelExportLxdContainerStatus::FAILED;
  }

  switch (response.status()) {
    case tremplin::CancelExportContainerResponse::CANCEL_QUEUED:
      return VirtualMachine::CancelExportLxdContainerStatus::CANCEL_QUEUED;
    case tremplin::CancelExportContainerResponse::OPERATION_NOT_FOUND:
      return VirtualMachine::CancelExportLxdContainerStatus::
          OPERATION_NOT_FOUND;
    default:
      return VirtualMachine::CancelExportLxdContainerStatus::UNKNOWN;
  }
}

VirtualMachine::ImportLxdContainerStatus VirtualMachine::ImportLxdContainer(
    const std::string& container_name,
    const std::string& import_path,
    uint64_t available_disk_space,
    std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::ImportLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::ImportContainerRequest request;
  vm_tools::tremplin::ImportContainerResponse response;

  request.set_container_name(container_name);
  request.set_import_path(import_path);
  request.set_available_disk_space(available_disk_space);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->ImportContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "ImportLxdContainer RPC failed: " << status.error_message()
               << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::ImportLxdContainerStatus::FAILED;
  }

  switch (response.status()) {
    case tremplin::ImportContainerResponse::IMPORTING:
      return VirtualMachine::ImportLxdContainerStatus::IMPORTING;
    case tremplin::ImportContainerResponse::FAILED:
      return VirtualMachine::ImportLxdContainerStatus::FAILED;
    default:
      return VirtualMachine::ImportLxdContainerStatus::UNKNOWN;
  }
}

VirtualMachine::CancelImportLxdContainerStatus
VirtualMachine::CancelImportLxdContainer(
    const std::string& in_progress_container_name, std::string* out_error) {
  DCHECK(out_error);
  if (!tremplin_stub_) {
    *out_error = "tremplin is not connected";
    return VirtualMachine::CancelImportLxdContainerStatus::FAILED;
  }

  vm_tools::tremplin::CancelImportContainerRequest request;
  vm_tools::tremplin::CancelImportContainerResponse response;

  request.set_in_progress_container_name(in_progress_container_name);

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->CancelImportContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "CancelImportLxdContainer RPC failed: "
               << status.error_message() << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::CancelImportLxdContainerStatus::FAILED;
  }

  switch (response.status()) {
    case tremplin::CancelImportContainerResponse::CANCEL_QUEUED:
      return VirtualMachine::CancelImportLxdContainerStatus::CANCEL_QUEUED;
    case tremplin::CancelImportContainerResponse::OPERATION_NOT_FOUND:
      return VirtualMachine::CancelImportLxdContainerStatus::
          OPERATION_NOT_FOUND;
    default:
      return VirtualMachine::CancelImportLxdContainerStatus::UNKNOWN;
  }
}

namespace {
vm_tools::tremplin::UpgradeContainerRequest::Version ConvertVersion(
    UpgradeContainerRequest::Version version) {
  switch (version) {
    case UpgradeContainerRequest::UNKNOWN:
      return vm_tools::tremplin::UpgradeContainerRequest::UNKNOWN;
    case UpgradeContainerRequest::DEBIAN_STRETCH:
      return vm_tools::tremplin::UpgradeContainerRequest::DEBIAN_STRETCH;
    case UpgradeContainerRequest::DEBIAN_BUSTER:
      return vm_tools::tremplin::UpgradeContainerRequest::DEBIAN_BUSTER;
    case UpgradeContainerRequest::DEBIAN_BULLSEYE:
      return vm_tools::tremplin::UpgradeContainerRequest::DEBIAN_BULLSEYE;
    default:
      return vm_tools::tremplin::UpgradeContainerRequest::UNKNOWN;
  }
}
}  // namespace

VirtualMachine::UpgradeContainerStatus VirtualMachine::UpgradeContainer(
    const Container* container,
    const UpgradeContainerRequest::Version& target_version,
    std::string* out_error) {
  DCHECK(container);
  DCHECK(out_error);

  vm_tools::tremplin::UpgradeContainerRequest request;
  vm_tools::tremplin::UpgradeContainerResponse response;

  request.set_container_name(container->name());
  request.set_target_version(ConvertVersion(target_version));

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->UpgradeContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "UpgradeLxdContainer RPC failed: " << status.error_message()
               << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::UpgradeContainerStatus::FAILED;
  }
  out_error->assign(response.failure_reason());
  switch (response.status()) {
    case tremplin::UpgradeContainerResponse::UNKNOWN:
      return VirtualMachine::UpgradeContainerStatus::UNKNOWN;
    case tremplin::UpgradeContainerResponse::STARTED:
      return VirtualMachine::UpgradeContainerStatus::STARTED;
    case tremplin::UpgradeContainerResponse::ALREADY_RUNNING:
      return VirtualMachine::UpgradeContainerStatus::ALREADY_RUNNING;
    case tremplin::UpgradeContainerResponse::NOT_SUPPORTED:
      return VirtualMachine::UpgradeContainerStatus::NOT_SUPPORTED;
    case tremplin::UpgradeContainerResponse::ALREADY_UPGRADED:
      return VirtualMachine::UpgradeContainerStatus::ALREADY_UPGRADED;
    case tremplin::UpgradeContainerResponse::FAILED:
      return VirtualMachine::UpgradeContainerStatus::FAILED;
    default:
      return VirtualMachine::UpgradeContainerStatus::UNKNOWN;
  }
}

VirtualMachine::CancelUpgradeContainerStatus
VirtualMachine::CancelUpgradeContainer(Container* container,
                                       std::string* out_error) {
  DCHECK(container);
  DCHECK(out_error);
  vm_tools::tremplin::CancelUpgradeContainerRequest request;
  vm_tools::tremplin::CancelUpgradeContainerResponse response;

  request.set_container_name(container->name());

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->CancelUpgradeContainer(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "CancelUpgradeLxdContainer RPC failed: "
               << status.error_message() << " " << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::CancelUpgradeContainerStatus::FAILED;
  }
  out_error->assign(response.failure_reason());
  switch (response.status()) {
    case tremplin::CancelUpgradeContainerResponse::UNKNOWN:
      return VirtualMachine::CancelUpgradeContainerStatus::UNKNOWN;
    case tremplin::CancelUpgradeContainerResponse::NOT_RUNNING:
      return VirtualMachine::CancelUpgradeContainerStatus::NOT_RUNNING;
    case tremplin::CancelUpgradeContainerResponse::CANCELLED:
      return VirtualMachine::CancelUpgradeContainerStatus::CANCELLED;
    case tremplin::CancelUpgradeContainerResponse::FAILED:
      return VirtualMachine::CancelUpgradeContainerStatus::FAILED;
    default:
      return VirtualMachine::CancelUpgradeContainerStatus::UNKNOWN;
  }
}

VirtualMachine::StartLxdStatus VirtualMachine::StartLxd(
    bool reset_lxd_db, std::string* out_error) {
  DCHECK(out_error);
  vm_tools::tremplin::StartLxdRequest request;
  vm_tools::tremplin::StartLxdResponse response;

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  request.set_reset_lxd_db(reset_lxd_db);

  grpc::Status status = tremplin_stub_->StartLxd(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "StartLxd RPC failed: " << status.error_message() << " "
               << status.error_code();
    out_error->assign(status.error_message());
    return VirtualMachine::StartLxdStatus::FAILED;
  }
  out_error->assign(response.failure_reason());
  switch (response.status()) {
    case tremplin::StartLxdResponse::UNKNOWN:
      return VirtualMachine::StartLxdStatus::UNKNOWN;
    case tremplin::StartLxdResponse::STARTING:
      return VirtualMachine::StartLxdStatus::STARTING;
    case tremplin::StartLxdResponse::ALREADY_RUNNING:
      return VirtualMachine::StartLxdStatus::ALREADY_RUNNING;
    case tremplin::StartLxdResponse::FAILED:
      return VirtualMachine::StartLxdStatus::FAILED;
    default:
      LOG(ERROR) << "Received unrecognised StartLxdStatus";
      return VirtualMachine::StartLxdStatus::UNKNOWN;
  }
}

void VirtualMachine::HostNetworkChanged() {
  if (!tremplin_stub_) {
    return;
  }

  vm_tools::tremplin::HostNetworkChangedRequest request;
  vm_tools::tremplin::HostNetworkChangedResponse response;

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status =
      tremplin_stub_->HostNetworkChanged(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "HostNetworkChanged RPC failed: " << status.error_message();
    return;
  }
}

bool VirtualMachine::GetTremplinDebugInfo(std::string* out) {
  if (!tremplin_stub_) {
    out->assign("Tremplin is not connected");
    return false;
  }

  vm_tools::tremplin::GetDebugInfoRequest request;
  vm_tools::tremplin::GetDebugInfoResponse response;

  grpc::ClientContext ctx;
  ctx.set_deadline(gpr_time_add(
      gpr_now(GPR_CLOCK_MONOTONIC),
      gpr_time_from_seconds(kLongOperationTimeoutSeconds, GPR_TIMESPAN)));

  grpc::Status status = tremplin_stub_->GetDebugInfo(&ctx, request, &response);
  if (!status.ok()) {
    LOG(ERROR) << "GetDebugInfo RPC failed: " << status.error_message();
    out->assign(status.error_message());
    return false;
  }
  out->assign(response.debug_information());
  return true;
}

}  // namespace cicerone
}  // namespace vm_tools
