// 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";
    debug_information->append(pkg_name.data(), pkg_name.size());
    *debug_information += "-";
    debug_information->append(pkg_version.data(), pkg_version.size());
    *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";
    debug_information->append(line.data(), line.size());
    *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";
    debug_information->append(line.data(), line.size());
    *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";
      debug_information->append(line.data(), line.size());
      *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
