// 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 <arpa/inet.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>

#include <iostream>
#include <memory>
#include <string>
#include <utility>

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/check_op.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop/message_pump_type.h>
#include <base/notreached.h>
#include <base/run_loop.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_piece.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <base/system/sys_info.h>
#include <base/task/single_thread_task_executor.h>
#include <base/threading/thread_task_runner_handle.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <chromeos/dbus/service_constants.h>
#include <crosvm/qcow_utils.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>
#include <vm_cicerone/proto_bindings/cicerone_service.pb.h>

using std::string;

namespace {

constexpr int kDefaultTimeoutMs = 120 * 1000;

void OnSignalConnected(const std::string& interface_name,
                       const std::string& signal_name,
                       bool is_connected) {
  LOG(INFO) << "D-Bus signal " << (is_connected ? "" : "NOT ")
            << "connected for " << interface_name << ":" << signal_name;
}

void OnContainerCreatedCallback(
    base::RunLoop* run_loop,
    vm_tools::cicerone::LxdContainerCreatedSignal::Status* final_status,
    std::string* failure_reason,
    dbus::Signal* signal) {
  dbus::MessageReader reader(signal);
  vm_tools::cicerone::LxdContainerCreatedSignal lccs;
  if (!reader.PopArrayOfBytesAsProto(&lccs)) {
    LOG(ERROR) << "Failed parsing LxdContainerCreatedSignal proto";
    return;
  }

  *final_status = lccs.status();
  *failure_reason = lccs.failure_reason();
  run_loop->Quit();
}

void OnContainerStartingCallback(
    base::RunLoop* run_loop,
    vm_tools::cicerone::LxdContainerStartingSignal::Status* final_status,
    std::string* failure_reason,
    dbus::Signal* signal) {
  dbus::MessageReader reader(signal);
  vm_tools::cicerone::LxdContainerStartingSignal lcss;
  if (!reader.PopArrayOfBytesAsProto(&lcss)) {
    LOG(ERROR) << "Failed parsing LxdContainerStartingSignal proto";
    return;
  }

  switch (lcss.status()) {
    case vm_tools::cicerone::LxdContainerStartingSignal::STARTED:
    case vm_tools::cicerone::LxdContainerStartingSignal::CANCELLED:
    case vm_tools::cicerone::LxdContainerStartingSignal::FAILED:
      *final_status = lcss.status();
      *failure_reason = lcss.failure_reason();
      run_loop->Quit();
      break;
    default:
      break;
  }
}

int CreateLxdContainer(dbus::ObjectProxy* proxy,
                       const string& vm_name,
                       const string& container_name,
                       const string& owner_id,
                       string image_server,
                       string image_alias,
                       string rootfs_path,
                       string metadata_path) {
  LOG(INFO) << "Creating LXD container";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kCreateLxdContainerMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::CreateLxdContainerRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_image_server(std::move(image_server));
  request.set_image_alias(std::move(image_alias));
  request.set_rootfs_path(std::move(rootfs_path));
  request.set_metadata_path(std::move(metadata_path));

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode CreateLxdContainer protobuf";
    return -1;
  }

  // RunLoop so we can monitor the D-Bus signals coming back to determine when
  // container creation has actually finished.
  base::RunLoop run_loop;
  vm_tools::cicerone::LxdContainerCreatedSignal::Status final_status =
      vm_tools::cicerone::LxdContainerCreatedSignal::UNKNOWN;
  std::string failure_reason = "Timed out waiting for reply";
  proxy->ConnectToSignal(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kLxdContainerCreatedSignal,
      base::Bind(&OnContainerCreatedCallback, base::Unretained(&run_loop),
                 &final_status, &failure_reason),
      base::Bind(&OnSignalConnected));

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::CreateLxdContainerResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  vm_tools::cicerone::CreateLxdContainerResponse::Status status =
      response.status();
  if (status != vm_tools::cicerone::CreateLxdContainerResponse::CREATING &&
      status != vm_tools::cicerone::CreateLxdContainerResponse::EXISTS) {
    LOG(ERROR) << "Failed to create LXD container: "
               << response.failure_reason();
    return -1;
  }

  if (status == vm_tools::cicerone::CreateLxdContainerResponse::EXISTS) {
    LOG(INFO) << "Container " << container_name << " already existed";
    return 0;
  } else {
    // Start the RunLoop which'll get the D-Bus signal callbacks and set the
    // final result for us.
    LOG(INFO) << "Waiting for D-Bus signal for container creation status";
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMinutes(10));
    run_loop.Run();

    if (final_status ==
        vm_tools::cicerone::LxdContainerCreatedSignal::CREATED) {
      LOG(INFO) << "Created container " << container_name << " successfully";
      return 0;
    } else {
      LOG(ERROR) << "Failed to create LXD container: " << failure_reason;
      return -1;
    }
  }
}

int StartLxdContainer(dbus::ObjectProxy* proxy,
                      const string& vm_name,
                      const string& container_name,
                      const string& owner_id) {
  LOG(INFO) << "Starting LXD container";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kStartLxdContainerMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::StartLxdContainerRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode StartLxdContainer protobuf";
    return -1;
  }

  // RunLoop so we can monitor the D-Bus signals coming back to determine when
  // starting the container has actually finished.
  base::RunLoop run_loop;
  vm_tools::cicerone::LxdContainerStartingSignal::Status final_status =
      vm_tools::cicerone::LxdContainerStartingSignal::UNKNOWN;
  std::string failure_reason = "Timed out waiting for reply";
  proxy->ConnectToSignal(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kLxdContainerStartingSignal,
      base::Bind(&OnContainerStartingCallback, base::Unretained(&run_loop),
                 &final_status, &failure_reason),
      base::Bind(&OnSignalConnected));

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::StartLxdContainerResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  vm_tools::cicerone::StartLxdContainerResponse::Status status =
      response.status();
  if (status == vm_tools::cicerone::StartLxdContainerResponse::FAILED ||
      status == vm_tools::cicerone::StartLxdContainerResponse::UNKNOWN) {
    LOG(ERROR) << "Failed to start LXD container: "
               << response.failure_reason();
    return -1;
  }

  if (status == vm_tools::cicerone::StartLxdContainerResponse::RUNNING) {
    LOG(INFO) << "Container " << container_name << " already running";
    return 0;
  } else {
    if (status == vm_tools::cicerone::StartLxdContainerResponse::REMAPPING) {
      LOG(INFO) << "Container is remapping filesystem; this can take a while";
    } else {
      DCHECK_EQ(status,
                vm_tools::cicerone::StartLxdContainerResponse::STARTING);
    }
    // Start the RunLoop which'll get the D-Bus signal callbacks and set the
    // final result for us.
    LOG(INFO) << "Waiting for D-Bus signal for container start status";
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMinutes(10));
    run_loop.Run();

    if (final_status ==
        vm_tools::cicerone::LxdContainerStartingSignal::STARTED) {
      LOG(INFO) << "Started container " << container_name << " successfully";
      return 0;
    } else {
      LOG(ERROR) << "Failed to start LXD container: " << failure_reason;
      return -1;
    }

    LOG(INFO) << "Started container: " << container_name;
    return 0;
  }
}

int SetTimezone(dbus::ObjectProxy* proxy, const string& timezone_name) {
  LOG(INFO) << "Setting timezone for VMs to " << timezone_name;

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kSetTimezoneMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::SetTimezoneRequest request;
  request.set_timezone_name(timezone_name);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode SetTimezone protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::SetTimezoneResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }

  LOG(INFO) << "Successfully set timezone for " << response.successes()
            << " containers to " << timezone_name;

  int failure_count = response.failure_reasons_size();
  if (failure_count != 0) {
    LOG(ERROR) << "Received " << failure_count << " failures:";
    for (int i = 0; i < failure_count; i++) {
      LOG(ERROR) << response.failure_reasons(i);
    }
    return -1;
  }
  return 0;
}

int GetLxdContainerUsername(dbus::ObjectProxy* proxy,
                            const string& vm_name,
                            const string& container_name,
                            const string& owner_id) {
  LOG(INFO) << "Getting LXD container primary username";

  dbus::MethodCall method_call(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kGetLxdContainerUsernameMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::GetLxdContainerUsernameRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode GetLxdContainerUsernameRequest protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::GetLxdContainerUsernameResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  vm_tools::cicerone::GetLxdContainerUsernameResponse::Status status =
      response.status();
  if (status != vm_tools::cicerone::GetLxdContainerUsernameResponse::SUCCESS) {
    LOG(ERROR) << "Failed to get primary username: "
               << response.failure_reason();
    return -1;
  }

  LOG(INFO) << "Container primary user is: " << response.username();
  return 0;
}

int SetUpLxdContainerUser(dbus::ObjectProxy* proxy,
                          const string& vm_name,
                          const string& container_name,
                          const string& owner_id,
                          string container_username) {
  LOG(INFO) << "Setting up LXD container user";

  dbus::MethodCall method_call(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kSetUpLxdContainerUserMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::SetUpLxdContainerUserRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_container_username(std::move(container_username));

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode SetUpLxdContainerUser protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::SetUpLxdContainerUserResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  vm_tools::cicerone::SetUpLxdContainerUserResponse::Status status =
      response.status();
  if (status != vm_tools::cicerone::SetUpLxdContainerUserResponse::EXISTS &&
      status != vm_tools::cicerone::SetUpLxdContainerUserResponse::SUCCESS) {
    LOG(ERROR) << "Failed to set up user: " << response.failure_reason();
    return -1;
  }

  if (status == vm_tools::cicerone::SetUpLxdContainerUserResponse::EXISTS) {
    LOG(INFO) << "Container user already exists";
    return 0;
  } else {
    LOG(INFO) << "Created user in container";
    return 0;
  }
}

int LaunchApplication(dbus::ObjectProxy* proxy,
                      string owner_id,
                      string name,
                      string container_name,
                      string application) {
  if (application.empty()) {
    LOG(ERROR) << "--application is required";
    return -1;
  }

  LOG(INFO) << "Starting application " << application << " in '" << name << ":"
            << container_name << "'";

  dbus::MethodCall method_call(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kLaunchContainerApplicationMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::LaunchContainerApplicationRequest request;
  request.set_owner_id(owner_id);
  request.set_vm_name(name);
  request.set_container_name(container_name);
  request.set_desktop_file_id(application);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode LaunchContainerApplicationRequest protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::LaunchContainerApplicationResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }

  if (!response.success()) {
    LOG(ERROR) << "Failed to launch application: " << response.failure_reason();
    return -1;
  }

  LOG(INFO) << "Launched application " << application << " in '" << name << ":"
            << container_name << "'";

  return 0;
}

void Write(const std::string& output_filepath, const std::string& content) {
  int content_size = content.size();
  if (content_size != base::WriteFile(base::FilePath(output_filepath),
                                      content.c_str(), content_size)) {
    LOG(ERROR) << "Failed to write to file " << output_filepath;
  }
}

int GetIcon(dbus::ObjectProxy* proxy,
            string owner_id,
            string name,
            string container_name,
            string application,
            int icon_size,
            int scale,
            string output_filepath) {
  if (application.empty()) {
    LOG(ERROR) << "--application is required";
    return -1;
  }

  if (output_filepath.empty()) {
    LOG(ERROR) << "--output_filepath is required";
    return -1;
  }

  LOG(INFO) << "Getting icon for " << application << " in '" << name << ":"
            << container_name << "'";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kGetContainerAppIconMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::ContainerAppIconRequest request;
  request.set_owner_id(owner_id);
  request.set_vm_name(name);
  request.set_container_name(container_name);
  request.add_desktop_file_ids(application);
  request.set_size(icon_size);
  request.set_scale(scale);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode ContainerAppIconRequest protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::ContainerAppIconResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }

  // This should have up to one icon since the input has only one application
  // file ID.
  CHECK_LE(response.icons_size(), 1);
  for (vm_tools::cicerone::DesktopIcon icon : response.icons()) {
    if (!icon.icon().empty())
      Write(output_filepath, icon.icon());
  }

  return 0;
}

int GetInfo(dbus::ObjectProxy* proxy) {
  LOG(INFO) << "Getting information";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kGetDebugInformationMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::GetDebugInformationRequest request;

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode GetDebugInformationRequest protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::GetDebugInformationResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }

  std::cout << response.debug_information();

  return 0;
}

int GetLinuxPackageInfo(dbus::ObjectProxy* proxy,
                        const string& vm_name,
                        const string& container_name,
                        const string& owner_id,
                        string file_path) {
  if (file_path.empty()) {
    LOG(ERROR) << "--file_path is required";
    return -1;
  }
  LOG(INFO) << "Getting Linux package info";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kGetLinuxPackageInfoMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::LinuxPackageInfoRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_file_path(file_path);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode LinuxPackageInfoRequest protobuf";
    return -1;
  }

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::LinuxPackageInfoResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  if (!response.success()) {
    LOG(ERROR) << "Failure getting Linux package info: "
               << response.failure_reason();
    return -1;
  }
  LOG(INFO) << "Linux package info for: " << file_path;
  LOG(INFO) << "Package ID: " << response.package_id();
  LOG(INFO) << "License: " << response.license();
  LOG(INFO) << "Description: " << response.description();
  LOG(INFO) << "Project URL: " << response.project_url();
  LOG(INFO) << "Size(bytes): " << response.size();
  LOG(INFO) << "Summary: " << response.summary();
  return 0;
}

void OnApplicationInstalledCallback(
    base::RunLoop* run_loop,
    vm_tools::cicerone::InstallLinuxPackageProgressSignal::Status* final_status,
    std::string* failure_details,
    dbus::Signal* signal) {
  dbus::MessageReader reader(signal);
  vm_tools::cicerone::InstallLinuxPackageProgressSignal ilpps;
  if (!reader.PopArrayOfBytesAsProto(&ilpps)) {
    LOG(ERROR) << "Failed parsing InstallLinuxPackageProgressSignal proto";
    return;
  }

  if (ilpps.status() ==
      vm_tools::cicerone::InstallLinuxPackageProgressSignal::DOWNLOADING) {
    LOG(INFO) << "Downloading install packages, progress: "
              << ilpps.progress_percent();
    return;
  } else if (ilpps.status() ==
             vm_tools::cicerone::InstallLinuxPackageProgressSignal::
                 INSTALLING) {
    LOG(INFO) << "Installing packages, progress: " << ilpps.progress_percent();
    return;
  }

  *final_status = ilpps.status();
  *failure_details = ilpps.failure_details();
  run_loop->Quit();
}

int InstallLinuxPackage(dbus::ObjectProxy* proxy,
                        const string& vm_name,
                        const string& container_name,
                        const string& owner_id,
                        string file_path) {
  if (file_path.empty()) {
    LOG(ERROR) << "--file_path is required";
    return -1;
  }
  LOG(INFO) << "Installing Linux package";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kInstallLinuxPackageMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::InstallLinuxPackageRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_file_path(std::move(file_path));

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode InstallLinuxPackageRequest protobuf";
    return -1;
  }

  // RunLoop so we can monitor the D-Bus signals coming back to determine when
  // application install has actually finished.
  base::RunLoop run_loop;
  vm_tools::cicerone::InstallLinuxPackageProgressSignal::Status final_status =
      vm_tools::cicerone::InstallLinuxPackageProgressSignal::FAILED;
  std::string failure_details = "Timed out waiting for reply";
  proxy->ConnectToSignal(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kInstallLinuxPackageProgressSignal,
      base::Bind(&OnApplicationInstalledCallback, base::Unretained(&run_loop),
                 &final_status, &failure_details),
      base::Bind(&OnSignalConnected));

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::InstallLinuxPackageResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  switch (response.status()) {
    case vm_tools::cicerone::InstallLinuxPackageResponse::STARTED:
      LOG(INFO) << "Successfully started the package install";
      // Start the RunLoop which'll get the D-Bus signal callbacks and set the
      // final result for us.
      LOG(INFO) << "Waiting for D-Bus signal for application install status";
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMinutes(10));
      run_loop.Run();

      if (final_status ==
          vm_tools::cicerone::InstallLinuxPackageProgressSignal::SUCCEEDED) {
        LOG(INFO) << "Finished application install successfully";
        return 0;
      } else {
        LOG(ERROR) << "Failed to install application: " << failure_details;
        return -1;
      }
    case vm_tools::cicerone::InstallLinuxPackageResponse::
        INSTALL_ALREADY_ACTIVE:
      LOG(ERROR) << "Failed starting the package install because one is "
                    "already active";
      return -1;
    default:
      LOG(ERROR) << "Failed starting the package install, reason: "
                 << response.failure_reason();
      return -1;
  }
}

void OnApplicationUninstalledCallback(
    base::RunLoop* run_loop,
    vm_tools::cicerone::UninstallPackageProgressSignal::Status* final_status,
    std::string* failure_details,
    dbus::Signal* signal) {
  dbus::MessageReader reader(signal);
  vm_tools::cicerone::UninstallPackageProgressSignal progress_signal;
  if (!reader.PopArrayOfBytesAsProto(&progress_signal)) {
    LOG(ERROR) << "Failed parsing UninstallPackageProgressSignal proto";
    return;
  }

  if (progress_signal.status() ==
      vm_tools::cicerone::UninstallPackageProgressSignal::UNINSTALLING) {
    LOG(INFO) << "Uninstall packages, progress: "
              << progress_signal.progress_percent();
    return;
  }

  *final_status = progress_signal.status();
  *failure_details = progress_signal.failure_details();
  run_loop->Quit();
}

int UninstallApplication(dbus::ObjectProxy* proxy,
                         const string& vm_name,
                         const string& container_name,
                         const string& owner_id,
                         const string& application) {
  if (application.empty()) {
    LOG(ERROR) << "--application is required";
    return -1;
  }
  LOG(INFO) << "Uninstalling application";

  dbus::MethodCall method_call(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kUninstallPackageOwningFileMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::UninstallPackageOwningFileRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_desktop_file_id(application);

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode UninstallPackageOwningFileRequest protobuf";
    return -1;
  }

  // RunLoop so we can monitor the D-Bus signals coming back to determine when
  // application uninstall has actually finished.
  base::RunLoop run_loop;
  vm_tools::cicerone::UninstallPackageProgressSignal::Status final_status =
      vm_tools::cicerone::UninstallPackageProgressSignal::FAILED;
  std::string failure_details = "Timed out waiting for reply";
  proxy->ConnectToSignal(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kUninstallPackageProgressSignal,
      base::Bind(&OnApplicationUninstalledCallback, base::Unretained(&run_loop),
                 &final_status, &failure_details),
      base::Bind(&OnSignalConnected));

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::UninstallPackageOwningFileResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  switch (response.status()) {
    case vm_tools::cicerone::UninstallPackageOwningFileResponse::STARTED:
      LOG(INFO) << "Successfully started the package uninstall";
      // Start the RunLoop which'll get the D-Bus signal callbacks and set the
      // final result for us.
      LOG(INFO) << "Waiting for D-Bus signal for application uninstall status";
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMinutes(10));
      run_loop.Run();

      if (final_status ==
          vm_tools::cicerone::UninstallPackageProgressSignal::SUCCEEDED) {
        LOG(INFO) << "Finished application uninstall successfully";
        return 0;
      } else {
        LOG(ERROR) << "Failed to uninstall application: " << failure_details;
        return -1;
      }
    case vm_tools::cicerone::UninstallPackageOwningFileResponse::
        BLOCKING_OPERATION_IN_PROGRESS:
      LOG(ERROR) << "Failed starting the package uninstall because one is "
                    "already active";
      return -1;
    default:
      LOG(ERROR) << "Failed starting the package uninstall, reason: "
                 << response.failure_reason();
      return -1;
  }
}

void OnPlaybookAppliedCallback(
    base::RunLoop* run_loop,
    vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::Status*
        final_status,
    std::string* failure_details,
    dbus::Signal* signal) {
  dbus::MessageReader reader(signal);
  vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal progress_signal;
  if (!reader.PopArrayOfBytesAsProto(&progress_signal)) {
    LOG(ERROR) << "Failed parsing ApplyAnsiblePlaybookProgressSignal proto";
    return;
  }

  if (progress_signal.status() ==
      vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::IN_PROGRESS) {
    LOG(INFO) << "Applying playbook...";
    return;
  }

  *final_status = progress_signal.status();
  *failure_details = progress_signal.failure_details();
  run_loop->Quit();
}

int ApplyAnsiblePlaybook(dbus::ObjectProxy* proxy,
                         const string& vm_name,
                         const string& container_name,
                         const string& owner_id,
                         string playbook) {
  if (playbook.empty()) {
    LOG(ERROR) << "--playbook is required";
    return -1;
  }
  LOG(INFO) << "Applying Ansible playbook";

  dbus::MethodCall method_call(vm_tools::cicerone::kVmCiceroneInterface,
                               vm_tools::cicerone::kApplyAnsiblePlaybookMethod);
  dbus::MessageWriter writer(&method_call);

  vm_tools::cicerone::ApplyAnsiblePlaybookRequest request;
  request.set_vm_name(vm_name);
  request.set_container_name(container_name);
  request.set_owner_id(owner_id);
  request.set_playbook(std::move(playbook));

  if (!writer.AppendProtoAsArrayOfBytes(request)) {
    LOG(ERROR) << "Failed to encode ApplyAnsiblePlaybookRequest protobuf";
    return -1;
  }

  // RunLoop so we can monitor the D-Bus signals coming back to determine when
  // playbook application has actually finished.
  base::RunLoop run_loop;
  vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::Status final_status =
      vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::FAILED;
  std::string failure_details = "Timed out waiting for reply";
  proxy->ConnectToSignal(
      vm_tools::cicerone::kVmCiceroneInterface,
      vm_tools::cicerone::kApplyAnsiblePlaybookProgressSignal,
      base::Bind(&OnPlaybookAppliedCallback, base::Unretained(&run_loop),
                 &final_status, &failure_details),
      base::Bind(&OnSignalConnected));

  std::unique_ptr<dbus::Response> dbus_response =
      proxy->CallMethodAndBlock(&method_call, kDefaultTimeoutMs);
  if (!dbus_response) {
    LOG(ERROR) << "Failed to send dbus message to cicerone service";
    return -1;
  }

  dbus::MessageReader reader(dbus_response.get());
  vm_tools::cicerone::ApplyAnsiblePlaybookResponse response;
  if (!reader.PopArrayOfBytesAsProto(&response)) {
    LOG(ERROR) << "Failed to parse response protobuf";
    return -1;
  }
  switch (response.status()) {
    case vm_tools::cicerone::ApplyAnsiblePlaybookResponse::STARTED:
      LOG(INFO) << "Successfully started the playbook application";
      // Start the RunLoop which'll get the D-Bus signal callbacks and set the
      // final result for us.
      LOG(INFO) << "Waiting for D-Bus signal for playbook application status";
      base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
          FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMinutes(10));
      run_loop.Run();

      if (final_status ==
          vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::SUCCEEDED) {
        LOG(INFO) << "Finished playbook application successfully";
        return 0;
      }
      LOG(ERROR) << "Failed to apply playbook: " << failure_details;
      return -1;
    case vm_tools::cicerone::ApplyAnsiblePlaybookResponse::FAILED:
      LOG(ERROR) << "Failed starting the playbook application, reason: "
                 << response.failure_reason();
      return -1;
    default:
      NOTREACHED();
      return -1;
  }
}

}  // namespace

int main(int argc, char** argv) {
  base::AtExitManager at_exit;

  // Operations.
  DEFINE_bool(create_lxd_container, false, "Create an LXD container");
  DEFINE_bool(start_lxd_container, false, "Start an LXD container");
  DEFINE_bool(set_timezone, false, "Set timezone for all known LXD containers");
  DEFINE_bool(get_username, false, "Get the primary username in a container");
  DEFINE_bool(set_up_lxd_user, false, "Set up a user in an LXD container");
  DEFINE_bool(launch_application, false,
              "Launches an application in a container");
  DEFINE_bool(get_icon, false, "Get an app icon from a container within a VM");
  DEFINE_bool(get_info, false, "Get debug information about all running VMs");
  DEFINE_bool(install_package, false, "Install a Linux package file");
  DEFINE_bool(uninstall_application, false, "Uninstall an application");
  DEFINE_bool(package_info, false, "Gets information on a Linux package file");
  DEFINE_bool(apply_playbook, false, "Apply an Ansible playbook");

  // Parameters.
  DEFINE_string(vm_name, "", "VM name");
  DEFINE_string(container_name, "", "Container name");
  DEFINE_string(owner_id, "", "User id");
  DEFINE_string(image_server, "", "Image server to pull a container from");
  DEFINE_string(image_alias, "", "Container image alias");
  DEFINE_string(rootfs_path, "", "Path to rootfs tarball");
  DEFINE_string(metadata_path, "", "Path to metadata tarball");
  DEFINE_string(container_username, "", "Container username");
  DEFINE_string(application, "", "Name of the application to launch");
  DEFINE_string(output_filepath, "",
                "Filename with path to write appliction icon to");
  DEFINE_string(timezone_name, "",
                "The timezone to set, for example 'America/Denver'. "
                "See /usr/share/zoneinfo for other valid names.");
  DEFINE_int32(icon_size, 48,
               "The size of the icon to get is this icon_size by icon_size");
  DEFINE_int32(scale, 1, "The scale that the icon is designed to use with");
  DEFINE_string(file_path, "", "Package file path");
  DEFINE_string(playbook, "", "Ansible playbook content");

  brillo::FlagHelper::Init(argc, argv, "vm_cicerone client tool");
  brillo::InitLog(brillo::kLogToStderrIfTty);

  base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);
  base::FileDescriptorWatcher watcher(task_executor.task_runner());

  dbus::Bus::Options opts;
  opts.bus_type = dbus::Bus::SYSTEM;
  scoped_refptr<dbus::Bus> bus(new dbus::Bus(std::move(opts)));

  if (!bus->Connect()) {
    LOG(ERROR) << "Failed to connect to system bus";
    return -1;
  }

  dbus::ObjectProxy* proxy = bus->GetObjectProxy(
      vm_tools::cicerone::kVmCiceroneServiceName,
      dbus::ObjectPath(vm_tools::cicerone::kVmCiceroneServicePath));
  if (!proxy) {
    LOG(ERROR) << "Unable to get dbus proxy for "
               << vm_tools::cicerone::kVmCiceroneServiceName;
    return -1;
  }

  // The standard says that bool to int conversion is implicit and that
  // false => 0 and true => 1.
  // clang-format off
  if (FLAGS_create_lxd_container + FLAGS_start_lxd_container +
      FLAGS_set_timezone + FLAGS_set_up_lxd_user + FLAGS_get_username +
      FLAGS_launch_application + FLAGS_get_icon + FLAGS_get_info +
      FLAGS_install_package + FLAGS_uninstall_application +
      FLAGS_package_info + FLAGS_apply_playbook != 1) {
    // clang-format on
    LOG(ERROR) << "Exactly one of --create_lxd_container, "
               << "--start_lxd_container, --set_up_lxd_user, --set_timezone, "
               << "--get_username, --launch_application, --get_icon, "
               << "--get_info, --install_package, --uninstall_application, "
               << "--apply_playbook, or --package_info must be provided";
    return -1;
  }

  // Check for the get_info and set_timezone commands early because they do
  // not require owner ID, VM name, or container name.
  if (FLAGS_get_info) {
    return GetInfo(proxy);
  }

  if (FLAGS_set_timezone) {
    return SetTimezone(proxy, FLAGS_timezone_name);
  }

  // Every other D-Bus method for cicerone requires owner ID, VM name, and
  // container name.
  if (FLAGS_owner_id.empty()) {
    LOG(ERROR) << "--owner_id is required";
    return -1;
  }

  if (FLAGS_vm_name.empty()) {
    LOG(ERROR) << "--vm_name is required";
    return -1;
  }

  if (FLAGS_container_name.empty()) {
    LOG(ERROR) << "--container_name is required";
    return -1;
  }

  if (FLAGS_create_lxd_container) {
    return CreateLxdContainer(
        proxy, FLAGS_vm_name, FLAGS_container_name, FLAGS_owner_id,
        std::move(FLAGS_image_server), std::move(FLAGS_image_alias),
        std::move(FLAGS_rootfs_path), std::move(FLAGS_metadata_path));
  } else if (FLAGS_start_lxd_container) {
    return StartLxdContainer(proxy, FLAGS_vm_name, FLAGS_container_name,
                             FLAGS_owner_id);
  } else if (FLAGS_set_up_lxd_user) {
    return SetUpLxdContainerUser(proxy, FLAGS_vm_name, FLAGS_container_name,
                                 FLAGS_owner_id,
                                 std::move(FLAGS_container_username));
  } else if (FLAGS_get_username) {
    return GetLxdContainerUsername(proxy, FLAGS_vm_name, FLAGS_container_name,
                                   FLAGS_owner_id);
  } else if (FLAGS_launch_application) {
    return LaunchApplication(
        proxy, std::move(FLAGS_owner_id), std::move(FLAGS_vm_name),
        std::move(FLAGS_container_name), std::move(FLAGS_application));
  } else if (FLAGS_get_icon) {
    return GetIcon(proxy, std::move(FLAGS_owner_id), std::move(FLAGS_vm_name),
                   std::move(FLAGS_container_name),
                   std::move(FLAGS_application), FLAGS_icon_size, FLAGS_scale,
                   std::move(FLAGS_output_filepath));
  } else if (FLAGS_install_package) {
    return InstallLinuxPackage(proxy, FLAGS_vm_name, FLAGS_container_name,
                               FLAGS_owner_id, std::move(FLAGS_file_path));
  } else if (FLAGS_uninstall_application) {
    return UninstallApplication(proxy, FLAGS_vm_name, FLAGS_container_name,
                                FLAGS_owner_id, FLAGS_application);
  } else if (FLAGS_package_info) {
    return GetLinuxPackageInfo(proxy, FLAGS_vm_name, FLAGS_container_name,
                               FLAGS_owner_id, std::move(FLAGS_file_path));
  } else if (FLAGS_apply_playbook) {
    return ApplyAnsiblePlaybook(proxy, FLAGS_vm_name, FLAGS_container_name,
                                FLAGS_owner_id, std::move(FLAGS_playbook));
  }

  // Unreachable.
  return 0;
}
