// 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/garcon/service_impl.h"

#include <sys/socket.h>

#include <linux/vm_sockets.h>  // Needs to come after sys/socket

#include <algorithm>
#include <cstdlib>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/process/launch.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "vm_tools/common/spawn_util.h"
#include "vm_tools/garcon/ansible_playbook_application.h"
#include "vm_tools/garcon/arc_sideload.h"
#include "vm_tools/garcon/desktop_file.h"
#include "vm_tools/garcon/host_notifier.h"
#include "vm_tools/garcon/icon_finder.h"
#include "vm_tools/garcon/package_kit_proxy.h"

namespace vm_tools {
namespace garcon {
namespace {

constexpr char kStartupIDEnv[] = "DESKTOP_STARTUP_ID";
constexpr char kXDisplayEnv[] = "DISPLAY";
constexpr char kXLowDensityDisplayEnv[] = "DISPLAY_LOW_DENSITY";
constexpr char kWaylandDisplayEnv[] = "WAYLAND_DISPLAY";
constexpr char kWaylandLowDensityDisplayEnv[] = "WAYLAND_DISPLAY_LOW_DENSITY";
constexpr char kXCursorSizeEnv[] = "XCURSOR_SIZE";
constexpr char kLowDensityXCursorSizeEnv[] = "XCURSOR_SIZE_LOW_DENSITY";
constexpr size_t kMaxIconSize = 1048576;  // 1MB, very large for an icon

}  // namespace

ServiceImpl::ServiceImpl(PackageKitProxy* package_kit_proxy,
                         base::TaskRunner* task_runner,
                         HostNotifier* host_notifier)
    : package_kit_proxy_(package_kit_proxy),
      task_runner_(task_runner),
      host_notifier_(host_notifier) {
  CHECK(package_kit_proxy_);
}

grpc::Status ServiceImpl::LaunchApplication(
    grpc::ServerContext* ctx,
    const vm_tools::container::LaunchApplicationRequest* request,
    vm_tools::container::LaunchApplicationResponse* response) {
  LOG(INFO) << "Received request to launch application in container";

  if (request->desktop_file_id().empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "missing desktop_file_id");
  }

  // Find the actual file path that corresponds to this desktop file id.
  base::FilePath file_path =
      DesktopFile::FindFileForDesktopId(request->desktop_file_id());
  if (file_path.empty()) {
    response->set_success(false);
    response->set_failure_reason("Desktop file does not exist");
    return grpc::Status::OK;
  }

  // Now parse the actual desktop file.
  std::unique_ptr<DesktopFile> desktop_file =
      DesktopFile::ParseDesktopFile(file_path);
  if (!desktop_file) {
    response->set_success(false);
    response->set_failure_reason("Desktop file contents are invalid");
    return grpc::Status::OK;
  }

  // Make sure this desktop file is for an application.
  if (!desktop_file->IsApplication()) {
    response->set_success(false);
    response->set_failure_reason("Desktop file is not for an application");
    return grpc::Status::OK;
  }

  std::vector<std::string> files(request->files().begin(),
                                 request->files().end());

  // Get the argv string from the desktop file we need for execution.
  // TODO(timloh): Desktop files using %u/%f should execute multiple copies of
  // the program for multiple files.
  std::vector<std::string> argv = desktop_file->GenerateArgvWithFiles(files);
  if (argv.empty()) {
    response->set_success(false);
    response->set_failure_reason(
        "Failure in generating argv list for application");
    return grpc::Status::OK;
  }

  std::map<std::string, std::string> env;
  if (desktop_file->startup_notify()) {
    env[kStartupIDEnv] = request->desktop_file_id();
  }

  if (request->display_scaling() ==
      vm_tools::container::LaunchApplicationRequest::SCALED) {
    env[kXDisplayEnv] = std::getenv(kXLowDensityDisplayEnv);
    env[kWaylandDisplayEnv] = std::getenv(kWaylandLowDensityDisplayEnv);
    env[kXCursorSizeEnv] = std::getenv(kLowDensityXCursorSizeEnv);
  }

  // Discard child's process stdio,
  int stdio_fd[] = {-1, -1, -1};

  if (!Spawn(std::move(argv), std::move(env), desktop_file->path(), stdio_fd)) {
    response->set_success(false);
    response->set_failure_reason("Failure in execution of application");
  } else {
    response->set_success(true);
  }

  // Return OK no matter what because the RPC itself succeeded even if there
  // was an issue with launching the process.
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetIcon(
    grpc::ServerContext* ctx,
    const vm_tools::container::IconRequest* request,
    vm_tools::container::IconResponse* response) {
  LOG(INFO) << "Received request to get application icons in container";

  for (const std::string& desktop_file_id : request->desktop_file_ids()) {
    std::string icon_data;
    base::FilePath icon_filepath =
        LocateIconFile(desktop_file_id, request->icon_size(), request->scale());
    if (icon_filepath.empty()) {
      continue;
    }
    if (!base::ReadFileToStringWithMaxSize(icon_filepath, &icon_data,
                                           kMaxIconSize)) {
      LOG(ERROR) << "Failed to read icon data file " << icon_filepath.value();
      continue;
    }
    container::DesktopIcon* desktop_icon = response->add_desktop_icons();
    desktop_icon->set_desktop_file_id(desktop_file_id);
    desktop_icon->set_icon(icon_data);
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::LaunchVshd(
    grpc::ServerContext* ctx,
    const vm_tools::container::LaunchVshdRequest* request,
    vm_tools::container::LaunchVshdResponse* response) {
  LOG(INFO) << "Received request to launch vshd in container";

  if (request->port() == 0) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "vshd port cannot be 0");
  }

  std::vector<std::string> argv{
      "/opt/google/cros-containers/bin/vshd", "--inherit_env",
      base::StringPrintf("--forward_to_host_port=%u", request->port())};

  // Discard child's process stdio,
  int stdio_fd[] = {-1, -1, -1};

  if (!Spawn(std::move(argv), {}, "", stdio_fd)) {
    response->set_success(false);
    response->set_failure_reason("Failed to spawn vshd");
  } else {
    response->set_success(true);
  }

  // Return OK no matter what because the RPC itself succeeded even if there
  // was an issue with launching the process.
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetLinuxPackageInfo(
    grpc::ServerContext* ctx,
    const vm_tools::container::LinuxPackageInfoRequest* request,
    vm_tools::container::LinuxPackageInfoResponse* response) {
  LOG(INFO) << "Received request to get Linux package info";
  if (request->file_path().empty() && request->package_name().empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "file_path and package_name cannot both be empty");
  }

  std::string error_msg;
  std::shared_ptr<PackageKitProxy::LinuxPackageInfo> pkg_info =
      std::make_shared<PackageKitProxy::LinuxPackageInfo>();

  if (request->file_path().empty()) {
    response->set_success(
        package_kit_proxy_->GetLinuxPackageInfoFromPackageName(
            request->package_name(), pkg_info, &error_msg));
  } else {
    base::FilePath file_path(request->file_path());
    if (!base::PathExists(file_path)) {
      return grpc::Status(grpc::INVALID_ARGUMENT, "file_path does not exist");
    }
    response->set_success(package_kit_proxy_->GetLinuxPackageInfoFromFilePath(
        file_path, pkg_info, &error_msg));
  }

  if (response->success()) {
    response->set_package_id(std::move(pkg_info->package_id));
    response->set_license(std::move(pkg_info->license));
    response->set_description(std::move(pkg_info->description));
    response->set_project_url(std::move(pkg_info->project_url));
    response->set_size(pkg_info->size);
    response->set_summary(std::move(pkg_info->summary));
  } else {
    response->set_failure_reason(error_msg);
  }
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::InstallLinuxPackage(
    grpc::ServerContext* ctx,
    const vm_tools::container::InstallLinuxPackageRequest* request,
    vm_tools::container::InstallLinuxPackageResponse* response) {
  LOG(INFO) << "Received request to install Linux package";
  if (request->file_path().empty() && request->package_id().empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "file_path and package_id cannot both be empty");
  }
  std::string error_msg;
  if (request->file_path().empty()) {
    response->set_status(package_kit_proxy_->InstallLinuxPackageFromPackageId(
        request->package_id(), request->command_uuid(), &error_msg));
  } else {
    base::FilePath file_path(request->file_path());
    if (!base::PathExists(file_path)) {
      return grpc::Status(grpc::INVALID_ARGUMENT, "file_path does not exist");
    }
    response->set_status(package_kit_proxy_->InstallLinuxPackageFromFilePath(
        file_path, request->command_uuid(), &error_msg));
  }
  response->set_failure_reason(error_msg);
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::UninstallPackageOwningFile(
    grpc::ServerContext* ctx,
    const vm_tools::container::UninstallPackageOwningFileRequest* request,
    vm_tools::container::UninstallPackageOwningFileResponse* response) {
  LOG(INFO) << "Received request to uninstall package owning a file";
  if (request->desktop_file_id().empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "missing desktop_file_id");
  }

  // Find the actual file path that corresponds to this desktop file id.
  base::FilePath file_path =
      DesktopFile::FindFileForDesktopId(request->desktop_file_id());
  if (file_path.empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT,
                        "desktop_file_id does not exist");
  }

  std::string error;
  response->set_status(
      package_kit_proxy_->UninstallPackageOwningFile(file_path, &error));
  response->set_failure_reason(error);

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::GetDebugInformation(
    grpc::ServerContext* ctx,
    const vm_tools::container::GetDebugInformationRequest* request,
    vm_tools::container::GetDebugInformationResponse* response) {
  LOG(INFO) << "Received request to get container debug information";

  std::string* debug_information = response->mutable_debug_information();

  *debug_information += "Installed Crostini Packages:\n";
  std::string dpkg_out;
  base::GetAppOutput({"dpkg", "-l", "cros-*"}, &dpkg_out);
  std::vector<base::StringPiece> dpkg_lines = base::SplitStringPiece(
      dpkg_out, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const auto& pkg_line : dpkg_lines) {
    std::vector<base::StringPiece> pkg_info = base::SplitStringPiece(
        pkg_line, base::kWhitespaceASCII, base::TRIM_WHITESPACE,
        base::SPLIT_WANT_NONEMPTY);
    // Filter out unrelated lines.
    if (pkg_info.size() < 3)
      continue;
    // Only collect installed packages.
    if (pkg_info[0] != "ii")
      continue;

    base::StringPiece pkg_name = pkg_info[1];
    base::StringPiece pkg_version = pkg_info[2];

    *debug_information += "\t";
    pkg_name.AppendToString(debug_information);
    *debug_information += "-";
    pkg_version.AppendToString(debug_information);
    *debug_information += "\n";
  }

  *debug_information += "systemctl status:\n";
  std::string systemctl_out;
  base::GetAppOutput({"systemctl", "--no-legend"}, &systemctl_out);
  std::vector<base::StringPiece> systemctl_out_lines = base::SplitStringPiece(
      systemctl_out, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const auto& line : systemctl_out_lines) {
    *debug_information += "\t";
    line.AppendToString(debug_information);
    *debug_information += "\n";
  }

  *debug_information += "systemctl user status:\n";
  std::string systemctl_user_out;
  base::GetAppOutput({"systemctl", "--user", "--no-legend"},
                     &systemctl_user_out);
  std::vector<base::StringPiece> systemctl_user_out_lines =
      base::SplitStringPiece(systemctl_user_out, "\n", base::TRIM_WHITESPACE,
                             base::SPLIT_WANT_NONEMPTY);
  for (const auto& line : systemctl_user_out_lines) {
    *debug_information += "\t";
    line.AppendToString(debug_information);
    *debug_information += "\n";
  }

  auto user_services =
      std::vector<std::string>{"cros-garcon", "sommelier@0", "sommelier@1",
                               "sommelier-x@0", "sommelier-x@1"};
  for (const auto& service : user_services) {
    *debug_information += "Filtered journalctl for " + service + ":\n";
    std::string journalctl_user_out;
    base::GetAppOutput(
        {"journalctl", "--user-unit", service, "--since", "1 day ago"},
        &journalctl_user_out);
    std::vector<base::StringPiece> systemctl_user_out_lines =
        base::SplitStringPiece(journalctl_user_out, "\n", base::TRIM_WHITESPACE,
                               base::SPLIT_WANT_NONEMPTY);
    for (const auto& line : systemctl_user_out_lines) {
      *debug_information += "\t";
      line.AppendToString(debug_information);
      *debug_information += "\n";
    }
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::ConnectChunnel(
    grpc::ServerContext* ctx,
    const vm_tools::container::ConnectChunnelRequest* request,
    vm_tools::container::ConnectChunnelResponse* response) {
  LOG(INFO) << "Received request to connect to chunnel";

  if (request->chunneld_port() == 0)
    return grpc::Status(grpc::INVALID_ARGUMENT, "invalid chunneld port");

  if (request->target_tcp4_port() == 0)
    return grpc::Status(grpc::INVALID_ARGUMENT, "invalid target TCP4 port");

  std::vector<std::string> argv{
      "/opt/google/cros-containers/bin/chunnel", "--remote",
      base::StringPrintf("vsock:%u:%u", VMADDR_CID_HOST,
                         request->chunneld_port()),
      "--local",
      base::StringPrintf("localhost:%u", request->target_tcp4_port())};

  // Discard child's process stdio,
  int stdio_fd[] = {-1, -1, -1};

  if (!Spawn(std::move(argv), {}, "", stdio_fd)) {
    response->set_success(false);
    response->set_failure_reason("Failed to spawn chunnel");
  } else {
    response->set_success(true);
  }

  return grpc::Status::OK;
}

grpc::Status ServiceImpl::ApplyAnsiblePlaybook(
    grpc::ServerContext* ctx,
    const vm_tools::container::ApplyAnsiblePlaybookRequest* request,
    vm_tools::container::ApplyAnsiblePlaybookResponse* response) {
  LOG(INFO) << "Received request to apply Ansible playbook";
  if (request->playbook().empty()) {
    return grpc::Status(grpc::INVALID_ARGUMENT, "playbook cannot be empty");
  }

  AnsiblePlaybookApplication* ansible_playbook_application;
  std::string error_msg;
  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
  // AnsiblePlaybookApplication is created on garcon service tasks thread,
  // because Ansible playbook application task is using
  // base::FileDescriptorWatcher to watch ansible-playbook process stdio.
  bool ret = task_runner_->PostTask(
      FROM_HERE, base::Bind(&HostNotifier::CreateAnsiblePlaybookApplication,
                            base::Unretained(host_notifier_), &event,
                            &ansible_playbook_application));
  if (!ret) {
    error_msg =
        "Failed to post AnsiblePlaybookApplication creation to garcon "
        "service tasks thread";
    LOG(ERROR) << "Failed to start Ansible playbook application: " << error_msg;
    response->set_status(
        vm_tools::container::ApplyAnsiblePlaybookResponse::FAILED);
    response->set_failure_reason(error_msg);
    return grpc::Status::OK;
  }
  // Wait for the creation to complete.
  event.Wait();
  if (!ansible_playbook_application) {
    error_msg = "Failed in creating the AnsiblePlaybookApplication";
    LOG(ERROR) << "Failed to start Ansible playbook application: " << error_msg;
    response->set_status(
        vm_tools::container::ApplyAnsiblePlaybookResponse::FAILED);
    response->set_failure_reason(error_msg);
    return grpc::Status::OK;
  }
  event.Reset();
  ansible_playbook_application->AddObserver(host_notifier_);

  base::FilePath ansible_playbook_file_path =
      ansible_playbook_application->CreateAnsiblePlaybookFile(
          request->playbook(), &error_msg);

  if (ansible_playbook_file_path.empty()) {
    LOG(ERROR) << "Failed to create valid file with Ansible playbook, "
               << "error: " << error_msg;
    host_notifier_->RemoveAnsiblePlaybookApplication();
    response->set_status(
        vm_tools::container::ApplyAnsiblePlaybookResponse::FAILED);
    response->set_failure_reason(error_msg);
    return grpc::Status::OK;
  }

  LOG(INFO) << "Ansible playbook file created at "
            << ansible_playbook_file_path.value();

  bool success = ansible_playbook_application->ExecuteAnsiblePlaybook(
      ansible_playbook_file_path, &error_msg);

  if (!success) {
    LOG(ERROR) << "Failed to start Ansible playbook application: " << error_msg;
    host_notifier_->RemoveAnsiblePlaybookApplication();
    response->set_status(
        vm_tools::container::ApplyAnsiblePlaybookResponse::FAILED);
    response->set_failure_reason(error_msg);
    return grpc::Status::OK;
  }

  LOG(INFO) << "Ansible playbook application started";
  response->set_status(
      vm_tools::container::ApplyAnsiblePlaybookResponse::STARTED);
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::ConfigureForArcSideload(
    grpc::ServerContext* ctx,
    const vm_tools::container::ConfigureForArcSideloadRequest* request,
    vm_tools::container::ConfigureForArcSideloadResponse* response) {
  bool success = ArcSideload::Enable(response->mutable_failure_reason());
  response->set_status(
      success ? vm_tools::container::ConfigureForArcSideloadResponse::SUCCEEDED
              : vm_tools::container::ConfigureForArcSideloadResponse::FAILED);
  if (!success) {
    LOG(ERROR) << "Arc sideload configuration failed: "
               << response->failure_reason();
  }
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::AddFileWatch(
    grpc::ServerContext* ctx,
    const vm_tools::container::AddFileWatchRequest* request,
    vm_tools::container::AddFileWatchResponse* response) {
  std::string error_msg;
  if (host_notifier_->AddFileWatch(base::FilePath(request->path()),
                                   &error_msg)) {
    response->set_status(vm_tools::container::AddFileWatchResponse::SUCCEEDED);
  } else {
    response->set_status(vm_tools::container::AddFileWatchResponse::FAILED);
    response->set_failure_reason(error_msg);
  }
  return grpc::Status::OK;
}

grpc::Status ServiceImpl::RemoveFileWatch(
    grpc::ServerContext* ctx,
    const vm_tools::container::RemoveFileWatchRequest* request,
    vm_tools::container::RemoveFileWatchResponse* response) {
  std::string error_msg;
  if (host_notifier_->RemoveFileWatch(base::FilePath(request->path()),
                                      &error_msg)) {
    response->set_status(
        vm_tools::container::RemoveFileWatchResponse::SUCCEEDED);
  } else {
    response->set_status(vm_tools::container::RemoveFileWatchResponse::FAILED);
    response->set_failure_reason(error_msg);
  }
  return grpc::Status::OK;
}

}  // namespace garcon
}  // namespace vm_tools
