// 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 <signal.h>
#include <sys/signalfd.h>
#include <sys/socket.h>

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

#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>
#include <base/threading/thread_task_runner_handle.h>
#include <base/time/time.h>
#include <chromeos/constants/vm_tools.h>

#include "vm_tools/garcon/desktop_file.h"
#include "vm_tools/garcon/host_notifier.h"
#include "vm_tools/garcon/mime_types_parser.h"

namespace {

constexpr char kHostIpFile[] = "/dev/.host_ip";
constexpr char kSecurityTokenFile[] = "/dev/.container_token";
constexpr int kSecurityTokenLength = 36;
// File extension for desktop files.
constexpr char kDesktopFileExtension[] = ".desktop";
// Directory where the MIME types file is stored for watching with inotify.
constexpr char kMimeTypesDir[] = "/etc";
// File where MIME type information is stored in the container.
constexpr char kMimeTypesFilePath[] = "/etc/mime.types";
// Filename for the user's MIME types file in their home dir.
constexpr char kUserMimeTypesFile[] = ".mime.types";
// Duration over which we coalesce changes to the desktop file system.
constexpr base::TimeDelta kFilesystemChangeCoalesceTime =
    base::TimeDelta::FromSeconds(3);
// Delimiter for the end of a URL scheme.
constexpr char kUrlSchemeDelimiter[] = "://";

std::string GetHostIp() {
  char host_addr[INET_ADDRSTRLEN + 1];
  base::FilePath host_ip_path(kHostIpFile);
  int num_read = base::ReadFile(host_ip_path, host_addr, sizeof(host_addr) - 1);
  if (num_read <= 0) {
    LOG(ERROR) << "Failed reading the host IP from: "
               << host_ip_path.MaybeAsASCII();
    return "";
  }
  host_addr[num_read] = '\0';
  return std::string(host_addr);
}

std::string GetSecurityToken() {
  char token[kSecurityTokenLength + 1];
  base::FilePath security_token_path(kSecurityTokenFile);
  int num_read = base::ReadFile(security_token_path, token, sizeof(token) - 1);
  if (num_read <= 0) {
    LOG(ERROR) << "Failed reading the container token from: "
               << security_token_path.MaybeAsASCII();
    return "";
  }
  token[num_read] = '\0';
  return std::string(token);
}

void SendInstallStatusToHost(
    vm_tools::container::ContainerListener::Stub* stub,
    vm_tools::container::InstallLinuxPackageProgressInfo progress_info) {
  grpc::ClientContext ctx;
  vm_tools::EmptyMessage empty;
  grpc::Status grpc_status =
      stub->InstallLinuxPackageProgress(&ctx, progress_info, &empty);
  if (!grpc_status.ok()) {
    LOG(WARNING) << "Failed to notify host system about install status: "
                 << grpc_status.error_message();
  }
}

void SendUninstallStatusToHost(
    vm_tools::container::ContainerListener::Stub* stub,
    vm_tools::container::UninstallPackageProgressInfo info) {
  grpc::ClientContext ctx;
  vm_tools::EmptyMessage empty;
  grpc::Status grpc_status = stub->UninstallPackageProgress(&ctx, info, &empty);
  if (!grpc_status.ok()) {
    LOG(WARNING) << "Failed to notify host system about uninstall status: "
                 << grpc_status.error_message() << " (code "
                 << grpc_status.error_code() << ")";
  }
}

void SendApplyAnsiblePlaybookStatusToHost(
    vm_tools::container::ContainerListener::Stub* stub,
    vm_tools::container::ApplyAnsiblePlaybookProgressInfo info) {
  grpc::ClientContext ctx;
  vm_tools::EmptyMessage empty;
  grpc::Status grpc_status =
      stub->ApplyAnsiblePlaybookProgress(&ctx, info, &empty);
  if (!grpc_status.ok()) {
    LOG(WARNING) << "Failed to notify host system about ansible playbook "
                 << "application status: " << grpc_status.error_message()
                 << " (code " << grpc_status.error_code() << ")";
  }
}

}  // namespace

namespace vm_tools {
namespace garcon {

// static
std::unique_ptr<HostNotifier> HostNotifier::Create(
    base::Closure shutdown_closure) {
  return base::WrapUnique(new HostNotifier(std::move(shutdown_closure)));
}

// static
bool HostNotifier::OpenUrlInHost(const std::string& url) {
  std::string host_ip = GetHostIp();
  std::string token = GetSecurityToken();
  if (token.empty() || host_ip.empty()) {
    return false;
  }
  std::unique_ptr<vm_tools::container::ContainerListener::Stub> stub;
  stub = std::make_unique<vm_tools::container::ContainerListener::Stub>(
      grpc::CreateChannel(base::StringPrintf("vsock:%d:%u", VMADDR_CID_HOST,
                          vm_tools::kGarconPort),
                          grpc::InsecureChannelCredentials()));
  grpc::ClientContext ctx;
  vm_tools::container::OpenUrlRequest url_request;
  url_request.set_token(token);
  url_request.set_url(url);
  // If url has no scheme, but matches a local file, then convert to file://.
  auto front = url.find(kUrlSchemeDelimiter);
  if (front == std::string::npos) {
    base::FilePath path(url);
    base::FilePath abs = base::MakeAbsoluteFilePath(path);
    if (!abs.empty()) {
      url_request.set_url("file://" + abs.value());
    }
  }
  vm_tools::EmptyMessage empty;
  grpc::Status status = stub->OpenUrl(&ctx, url_request, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to request host system to open url \"" << url
                 << "\" error: " << status.error_message();
    return false;
  }
  return true;
}

bool HostNotifier::OpenTerminal(std::vector<std::string> args) {
  std::string host_ip = GetHostIp();
  std::string token = GetSecurityToken();
  if (token.empty() || host_ip.empty()) {
    return false;
  }
  std::unique_ptr<vm_tools::container::ContainerListener::Stub> stub;
  stub = std::make_unique<vm_tools::container::ContainerListener::Stub>(
      grpc::CreateChannel(base::StringPrintf("vsock:%d:%u", VMADDR_CID_HOST,
                          vm_tools::kGarconPort),
                          grpc::InsecureChannelCredentials()));
  grpc::ClientContext ctx;
  vm_tools::container::OpenTerminalRequest terminal_request;
  std::copy(std::make_move_iterator(args.begin()),
            std::make_move_iterator(args.end()),
            google::protobuf::RepeatedFieldBackInserter(
                terminal_request.mutable_params()));
  terminal_request.set_token(token);

  vm_tools::EmptyMessage empty;
  grpc::Status status = stub->OpenTerminal(&ctx, terminal_request, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed request to open terminal, error: "
                 << status.error_message();
    return false;
  }
  return true;
}

HostNotifier::HostNotifier(base::Closure shutdown_closure)
    : update_app_list_posted_(false),
      send_app_list_to_host_in_progress_(false),
      update_mime_types_posted_(false),
      shutdown_closure_(std::move(shutdown_closure)) {}

HostNotifier::~HostNotifier() = default;

void HostNotifier::OnSignalReadable() {
  signalfd_siginfo info;
  if (read(signal_fd_.get(), &info, sizeof(info)) != sizeof(info)) {
    PLOG(ERROR) << "Failed to read from signalfd";
  }
  DCHECK_EQ(info.ssi_signo, SIGTERM);
  // Notify the host we are shutting down, then inform our run loop to terminate
  // which should then shut us down, deallocate us and then also terminate the
  // gRPC thread.
  NotifyHostOfContainerShutdown();
  task_runner_->PostTask(FROM_HERE, shutdown_closure_);
}

void HostNotifier::OnInstallCompletion(const std::string& command_uuid,
                                       bool success,
                                       const std::string& failure_reason) {
  vm_tools::container::InstallLinuxPackageProgressInfo progress_info;
  progress_info.set_token(token_);
  progress_info.set_status(
      success ? vm_tools::container::InstallLinuxPackageProgressInfo::SUCCEEDED
              : vm_tools::container::InstallLinuxPackageProgressInfo::FAILED);
  progress_info.set_failure_details(failure_reason);
  progress_info.set_command_uuid(command_uuid);
  task_runner_->PostTask(FROM_HERE, base::Bind(&SendInstallStatusToHost,
                                               base::Unretained(stub_.get()),
                                               std::move(progress_info)));
}

void HostNotifier::OnInstallProgress(
    const std::string& command_uuid,
    vm_tools::container::InstallLinuxPackageProgressInfo::Status status,
    uint32_t percent_progress) {
  vm_tools::container::InstallLinuxPackageProgressInfo progress_info;
  progress_info.set_token(token_);
  progress_info.set_status(status);
  progress_info.set_progress_percent(percent_progress);
  progress_info.set_command_uuid(command_uuid);
  task_runner_->PostTask(FROM_HERE, base::Bind(&SendInstallStatusToHost,
                                               base::Unretained(stub_.get()),
                                               std::move(progress_info)));
}

void HostNotifier::OnUninstallCompletion(bool success,
                                         const std::string& failure_reason) {
  LOG(INFO) << "Got HostNotifier::OnUninstallCompletion(" << success << ", "
            << failure_reason << ")";
  vm_tools::container::UninstallPackageProgressInfo info;
  info.set_token(token_);
  if (success) {
    info.set_status(
        vm_tools::container::UninstallPackageProgressInfo::SUCCEEDED);
  } else {
    info.set_status(vm_tools::container::UninstallPackageProgressInfo::FAILED);
    info.set_failure_details(failure_reason);
  }
  task_runner_->PostTask(
      FROM_HERE, base::Bind(&SendUninstallStatusToHost,
                            base::Unretained(stub_.get()), std::move(info)));
}

void HostNotifier::OnUninstallProgress(uint32_t percent_progress) {
  VLOG(3) << "Got HostNotifier::OnUninstallProgress(" << percent_progress
          << ")";
  vm_tools::container::UninstallPackageProgressInfo info;
  info.set_token(token_);
  info.set_status(
      vm_tools::container::UninstallPackageProgressInfo::UNINSTALLING);
  info.set_progress_percent(percent_progress);
  task_runner_->PostTask(
      FROM_HERE, base::Bind(&SendUninstallStatusToHost,
                            base::Unretained(stub_.get()), std::move(info)));
}

void HostNotifier::OnApplyAnsiblePlaybookCompletion(
    bool success, const std::string& failure_reason) {
  LOG(INFO) << "Got HostNotifier::OnApplyAnsiblePlaybookCompletion(" << success
            << ", " << failure_reason << ")";
  RemoveAnsiblePlaybookApplication();

  vm_tools::container::ApplyAnsiblePlaybookProgressInfo info;
  info.set_token(token_);
  if (success) {
    info.set_status(
        vm_tools::container::ApplyAnsiblePlaybookProgressInfo::SUCCEEDED);
  } else {
    info.set_status(
        vm_tools::container::ApplyAnsiblePlaybookProgressInfo::FAILED);
    info.set_failure_details(failure_reason);
  }
  task_runner_->PostTask(
      FROM_HERE, base::Bind(&SendApplyAnsiblePlaybookStatusToHost,
                            base::Unretained(stub_.get()), std::move(info)));
}

void HostNotifier::CreateAnsiblePlaybookApplication(
    base::WaitableEvent* event,
    AnsiblePlaybookApplication** ansible_playbook_application_ptr) {
  DCHECK(!ansible_playbook_application_);
  ansible_playbook_application_ =
      std::make_unique<vm_tools::garcon::AnsiblePlaybookApplication>();
  *ansible_playbook_application_ptr = ansible_playbook_application_.get();
  event->Signal();
}

void HostNotifier::RemoveAnsiblePlaybookApplication() {
  ansible_playbook_application_->RemoveObserver(this);
  ansible_playbook_application_.reset();
}

bool HostNotifier::Init(uint32_t vsock_port,
                        PackageKitProxy* package_kit_proxy) {
  CHECK(package_kit_proxy);
  package_kit_proxy_ = package_kit_proxy;
  task_runner_ = base::ThreadTaskRunnerHandle::Get();
  std::string host_ip = GetHostIp();
  token_ = GetSecurityToken();
  if (token_.empty() || host_ip.empty()) {
    return false;
  }
  SetUpContainerListenerStub(std::move(host_ip));
  if (!NotifyHostGarconIsReady(vsock_port)) {
    return false;
  }

  // Start listening for SIGTERM.
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGTERM);

  signal_fd_.reset(signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK));
  if (!signal_fd_.is_valid()) {
    PLOG(ERROR) << "Unable to create signalfd";
    return false;
  }

  signal_controller_ = base::FileDescriptorWatcher::WatchReadable(
      signal_fd_.get(), base::BindRepeating(&HostNotifier::OnSignalReadable,
                                            base::Unretained(this)));
  if (!signal_controller_) {
    LOG(ERROR) << "Failed to watch signal file descriptor";
    return false;
  }

  // Block the standard SIGTERM handler since we will be getting it via the
  // signalfd. We have to do this before we setup the file path watcher
  // because that will end up spawning another thread for each watcher.
  if (sigprocmask(SIG_BLOCK, &mask, nullptr) < 0) {
    PLOG(ERROR) << "Failed blocking standard SIGTERM handler";
    return false;
  }

  // Setup all of our watchers for changes to any of the paths where .desktop
  // files may reside.
  std::vector<base::FilePath> watch_paths =
      DesktopFile::GetPathsForDesktopFiles();
  for (auto& path : watch_paths) {
    std::unique_ptr<base::FilePathWatcher> watcher =
        std::make_unique<base::FilePathWatcher>();
    if (!watcher->Watch(path, true,
                        base::Bind(&HostNotifier::DesktopPathsChanged,
                                   base::Unretained(this)))) {
      LOG(ERROR) << "Failed setting up filesystem path watcher for dir: "
                 << path.value();
      // Probably better to just watch the dirs we can rather than terminate
      // garcon altogether.
      continue;
    }
    watchers_.emplace_back(std::move(watcher));
  }

  // We can only watch directories and on changes we aren't notified which
  // file changes, so we end up watching for any changes in /etc or $HOME.

  // Also setup the watcher for the /etc/mime.types file.
  std::unique_ptr<base::FilePathWatcher> mime_type_watcher =
      std::make_unique<base::FilePathWatcher>();
  base::FilePath mime_type_path(kMimeTypesDir);
  if (!mime_type_watcher->Watch(mime_type_path, false,
                                base::Bind(&HostNotifier::MimeTypesChanged,
                                           base::Unretained(this)))) {
    LOG(ERROR) << "Failed setting up filesystem path watcher for: "
               << kMimeTypesDir;
  }
  watchers_.emplace_back(std::move(mime_type_watcher));

  // Also setup the watcher for the $HOME/.mime.types file.
  std::unique_ptr<base::FilePathWatcher> home_mime_type_watcher =
      std::make_unique<base::FilePathWatcher>();
  if (!home_mime_type_watcher->Watch(base::GetHomeDir(), false,
                                     base::Bind(&HostNotifier::MimeTypesChanged,
                                                base::Unretained(this)))) {
    LOG(ERROR) << "Failed setting up filesystem path watcher for: "
               << base::GetHomeDir().value();
  }
  watchers_.emplace_back(std::move(home_mime_type_watcher));

  // If this fails, don't terminate ourself, this could be some kind of
  // transient failure.
  SendAppListToHost();
  SendMimeTypesToHost();

  return true;
}

bool HostNotifier::NotifyHostGarconIsReady(uint32_t vsock_port) {
  // Notify the host system that we are ready.
  grpc::ClientContext ctx;
  vm_tools::container::ContainerStartupInfo startup_info;
  startup_info.set_token(token_);
  startup_info.set_garcon_port(vsock_port);
  vm_tools::EmptyMessage empty;
  grpc::Status status = stub_->ContainerReady(&ctx, startup_info, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to notify host system that container is ready: "
                 << status.error_message();
    return false;
  }
  return true;
}

void HostNotifier::NotifyHostOfContainerShutdown() {
  // Notify the host system that we are shutting down.
  grpc::ClientContext ctx;
  vm_tools::container::ContainerShutdownInfo shutdown_info;
  shutdown_info.set_token(token_);
  vm_tools::EmptyMessage empty;
  grpc::Status status = stub_->ContainerShutdown(&ctx, shutdown_info, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to notify host system that container is shutting "
                 << "down: " << status.error_message();
  }
}

void HostNotifier::NotifyHostOfPendingAppListUpdates() {
  grpc::ClientContext ctx;
  vm_tools::container::PendingAppListUpdateCount msg;
  msg.set_token(token_);
  msg.set_count(update_app_list_posted_ + send_app_list_to_host_in_progress_);
  vm_tools::EmptyMessage empty;
  grpc::Status status =
      stub_->PendingUpdateApplicationListCalls(&ctx, msg, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to notify host system of pending app list updates: "
                 << status.error_message();
  }
}

void HostNotifier::SendAppListToHost() {
  if (send_app_list_to_host_in_progress_) {
    // Don't have multiple SendAppListToHost callback chains happening at the
    // same time. Delay the next run a little longer.
    //
    // Checking a boolean isn't a race condition because all the callbacks are
    // on the same thread.
    task_runner_->PostDelayedTask(
        FROM_HERE,
        base::Bind(&HostNotifier::SendAppListToHost, base::Unretained(this)),
        kFilesystemChangeCoalesceTime);
    return;
  }

  auto callback_state = std::make_unique<AppListBuilderState>();
  callback_state->request.set_token(token_);

  // If we hit duplicate IDs, then we are supposed to use the first one only.
  std::set<std::string> unique_app_ids;

  // Get the list of directories that we should search for .desktop files
  // recursively and then perform the search.
  std::vector<base::FilePath> search_paths =
      DesktopFile::GetPathsForDesktopFiles();
  for (auto curr_path : search_paths) {
    base::FileEnumerator file_enum(curr_path, true,
                                   base::FileEnumerator::FILES);
    for (base::FilePath enum_path = file_enum.Next(); !enum_path.empty();
         enum_path = file_enum.Next()) {
      if (enum_path.FinalExtension() != kDesktopFileExtension) {
        continue;
      }
      // We have a .desktop file path, parse it and then add it to the
      // protobuf if it parses successfully.
      std::unique_ptr<DesktopFile> desktop_file =
          DesktopFile::ParseDesktopFile(enum_path);
      if (!desktop_file) {
        LOG(WARNING) << "Failed parsing the .desktop file: "
                     << enum_path.value();
        continue;
      }
      // If we have already seen this desktop file ID then don't analyze this
      // one. We want to check this before we do the filtering to allow users
      // to put .desktop files in local locations to hide applications in
      // system locations.
      if (!unique_app_ids.insert(desktop_file->app_id()).second) {
        continue;
      }
      // Make sure this .desktop file is one we should send to the host.
      // There are various cases where we do not want to transmit certain
      // .desktop files.
      if (!desktop_file->ShouldPassToHost()) {
        continue;
      }
      // Add this app to the list in the protobuf and populate all of its
      // fields.
      vm_tools::container::Application* app =
          callback_state->request.add_application();
      app->set_desktop_file_id(desktop_file->app_id());
      const std::map<std::string, std::string>& name_map =
          desktop_file->locale_name_map();
      vm_tools::container::Application::LocalizedString* names =
          app->mutable_name();
      for (const auto& name_entry : name_map) {
        vm_tools::container::Application::LocalizedString::StringWithLocale*
            locale_string = names->add_values();
        locale_string->set_locale(name_entry.first);
        locale_string->set_value(name_entry.second);
      }
      const std::map<std::string, std::string>& comment_map =
          desktop_file->locale_comment_map();
      vm_tools::container::Application::LocalizedString* comments =
          app->mutable_comment();
      for (const auto& comment_entry : comment_map) {
        vm_tools::container::Application::LocalizedString::StringWithLocale*
            locale_string = comments->add_values();
        locale_string->set_locale(comment_entry.first);
        locale_string->set_value(comment_entry.second);
      }
      const std::map<std::string, std::vector<std::string>>& keywords_map =
          desktop_file->locale_keywords_map();
      vm_tools::container::Application::LocaleStrings* keyword =
          app->mutable_keywords();
      for (const auto& keywords_entry : keywords_map) {
        vm_tools::container::Application::LocaleStrings::StringsWithLocale*
            locale_string = keyword->add_values();
        locale_string->set_locale(keywords_entry.first);
        for (const auto& curr_keyword : keywords_entry.second) {
          locale_string->add_value(curr_keyword);
        }
      }
      for (const auto& mime_type : desktop_file->mime_types()) {
        app->add_mime_types(mime_type);
      }

      app->set_no_display(desktop_file->no_display());
      app->set_startup_wm_class(desktop_file->startup_wm_class());
      app->set_startup_notify(desktop_file->startup_notify());
      app->set_executable_file_name(desktop_file->GenerateExecutableFileName());

      callback_state->desktop_files_for_application.push_back(enum_path);
    }
  }

  CHECK_EQ(callback_state->desktop_files_for_application.size(),
           callback_state->request.application_size());

  // We now want to query all the .desktop files to see what package owns them.
  // Unforuntately, this requires D-Bus calls to the PackageKit, and we are on
  // the D-Bus thread. So we can't receive the results until this function
  // returns, so we need to set up a series of callbacks.
  //
  // Query each .desktop file in turn. The callback will record the info for
  // that file and also kick off the query for the next file until all files
  // have been queried.
  callback_state->num_package_id_queries_completed = 0;

  // Clear this in case it was set, this all happens on the same thread.
  // Clear this now, not when the package_id callbacks are complete, in case
  // we get another notification while this is still in flight; we'd want to run
  // this function again in that case.
  update_app_list_posted_ = false;

  // Don't start another round of callbacks while still trying to finish this
  // round.
  send_app_list_to_host_in_progress_ = true;

  RequestNextPackageIdOrCompleteUpdateApplicationList(
      std::move(callback_state));
}

void HostNotifier::RequestNextPackageIdOrCompleteUpdateApplicationList(
    std::unique_ptr<AppListBuilderState> state) {
  if ((state->num_package_id_queries_completed >=
       state->desktop_files_for_application.size())) {
    // We have finished all package_id queries. This data is ready to send to
    // the host.
    send_app_list_to_host_in_progress_ = false;
    vm_tools::EmptyMessage empty;
    grpc::ClientContext ctx;
    grpc::Status status =
        stub_->UpdateApplicationList(&ctx, state->request, &empty);
    VLOG(3) << "UpdatedApplicationList\n" << state->request.DebugString();
    if (!status.ok()) {
      LOG(WARNING) << "Failed to notify host of the application list: "
                   << status.error_message();
    }
    NotifyHostOfPendingAppListUpdates();
    return;
  }
  // else we still need to do more package_id queries
  package_kit_proxy_->SearchLinuxPackagesForFile(
      state->desktop_files_for_application
          [state->num_package_id_queries_completed],
      base::Bind(&HostNotifier::PackageIdCallback, base::Unretained(this),
                 base::Passed(&state)));
}

void HostNotifier::PackageIdCallback(
    std::unique_ptr<AppListBuilderState> state,
    bool success,
    bool pkg_found,
    const PackageKitProxy::LinuxPackageInfo& pkg_info,
    const std::string& error) {
  // The data passed in the parameters is for the Application at
  // state->request.application[state->num_package_id_queries_completed]
  CHECK_LT(state->num_package_id_queries_completed,
           state->request.application_size());
  if (success && pkg_found) {
    vm_tools::container::Application* application =
        state->request.mutable_application(
            state->num_package_id_queries_completed);
    application->set_package_id(pkg_info.package_id);
  } else if (!success) {
    LOG(ERROR) << "Failed to get Package Info: " << error;
  }

  state->num_package_id_queries_completed++;
  task_runner_->PostTask(
      FROM_HERE,
      base::Bind(
          &HostNotifier::RequestNextPackageIdOrCompleteUpdateApplicationList,
          base::Unretained(this), base::Passed(&state)));
}

void HostNotifier::SendMimeTypesToHost() {
  vm_tools::container::UpdateMimeTypesRequest request;
  request.set_token(token_);
  vm_tools::EmptyMessage empty;

  // Clear this in case it was set, this all happens on the same thread.
  update_mime_types_posted_ = false;

  MimeTypeMap mime_type_map;
  if (!ParseMimeTypes(kMimeTypesFilePath, &mime_type_map)) {
    LOG(ERROR) << "Failed parsing system mime types, will not send the list to "
               << "host";
    return;
  }
  // The user MIME types may not be set up, so we ignore failures here. User
  // values override system values, so parse this one second so they get
  // overridden.
  ParseMimeTypes(base::GetHomeDir().Append(kUserMimeTypesFile).value(),
                 &mime_type_map);

  request.mutable_mime_type_mappings()->insert(
      std::make_move_iterator(mime_type_map.begin()),
      std::make_move_iterator(mime_type_map.end()));
  // Now make the gRPC call to send this list to the host.
  grpc::ClientContext ctx;
  grpc::Status status = stub_->UpdateMimeTypes(&ctx, request, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to notify host of the MIME types: "
                 << status.error_message();
  }
}

void HostNotifier::DesktopPathsChanged(const base::FilePath& path, bool error) {
  if (error) {
    // This should never occur because the implementation for Linux never calls
    // this with an error.
    LOG(ERROR) << "Error detected in file path watching for path: "
               << path.value();
    return;
  }

  // We don't want to trigger an update every time there's a change, instead
  // wait a bit and coalesce potential groups of changes that may occur. We
  // don't want to wait too long though because then the user may feel that it
  // is unresponsive in newly installed applications not showing up in the
  // launcher when they check.
  if (update_app_list_posted_) {
    return;
  }
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&HostNotifier::SendAppListToHost, base::Unretained(this)),
      kFilesystemChangeCoalesceTime);
  update_app_list_posted_ = true;
  NotifyHostOfPendingAppListUpdates();
}

void HostNotifier::MimeTypesChanged(const base::FilePath& path, bool error) {
  if (error) {
    // This should never occur because the implementation for Linux never calls
    // this with an error.
    LOG(ERROR) << "Error detected in file path watching for path: "
               << path.value();
    return;
  }

  // Coalesce these calls if we have one pending.
  if (update_mime_types_posted_) {
    return;
  }
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&HostNotifier::SendMimeTypesToHost, base::Unretained(this)),
      kFilesystemChangeCoalesceTime);
  update_mime_types_posted_ = true;
}

void HostNotifier::SetUpContainerListenerStub(const std::string& host_ip) {
  stub_ = std::make_unique<vm_tools::container::ContainerListener::Stub>(
      grpc::CreateChannel(base::StringPrintf("vsock:%d:%u", VMADDR_CID_HOST,
                                             vm_tools::kGarconPort),
                          grpc::InsecureChannelCredentials()));
}

bool HostNotifier::AddFileWatch(const base::FilePath& path,
                                std::string* error_msg) {
  if (path.IsAbsolute() || path.ReferencesParent()) {
    LOG(ERROR) << "Invalid path";
    *error_msg = "invalid path";
    return false;
  }
  if (file_path_watchers_.count(path) > 0) {
    LOG(ERROR) << "Already watching path";
    *error_msg = "already watching path";
    return false;
  }
  std::unique_ptr<base::FilePathWatcher> watcher =
      std::make_unique<base::FilePathWatcher>();
  base::FilePath path_in_home = base::GetHomeDir().Append(path);

  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(base::IgnoreResult(&base::FilePathWatcher::Watch),
                     base::Unretained(watcher.get()), path_in_home,
                     /*recursive=*/false,
                     base::BindRepeating(&HostNotifier::FileWatchTriggered,
                                         base::Unretained(this))));

  file_path_watchers_[path] = std::move(watcher);
  return true;
}

bool HostNotifier::RemoveFileWatch(const base::FilePath& path,
                                   std::string* error_msg) {
  if (path.IsAbsolute() || path.ReferencesParent()) {
    LOG(ERROR) << "Invalid path";
    *error_msg = "invalid path";
    return false;
  }
  if (file_path_watchers_.count(path) == 0) {
    LOG(ERROR) << "Not watching path";
    *error_msg = "not watching path";
    return false;
  }
  task_runner_->DeleteSoon(FROM_HERE, file_path_watchers_[path].release());
  file_path_watchers_.erase(path);
  file_watch_last_change_.erase(path);
  return true;
}

void HostNotifier::SendFileWatchTriggeredToHost(const base::FilePath& path) {
  vm_tools::container::FileWatchTriggeredInfo info;
  info.set_token(token_);
  info.set_path(path.value());
  vm_tools::EmptyMessage empty;

  // Update pending flag and time when last sent.
  file_watch_change_posted_.erase(path);
  file_watch_last_change_[path] = base::TimeTicks::Now();

  // Now make the gRPC call to notify the host.
  grpc::ClientContext ctx;
  grpc::Status status = stub_->FileWatchTriggered(&ctx, info, &empty);
  if (!status.ok()) {
    LOG(WARNING) << "Failed to notify host of FilePathWatcher change: "
                 << status.error_message();
  }
}

void HostNotifier::FileWatchTriggered(const base::FilePath& absolute_path,
                                      bool error) {
  if (error) {
    // This should never occur because the implementation for Linux never calls
    // this with an error.
    LOG(ERROR) << "Error detected in file path watcher";
    return;
  }

  base::FilePath home = base::GetHomeDir();
  base::FilePath path;
  if (absolute_path != home && !home.AppendRelativePath(absolute_path, &path)) {
    LOG(ERROR) << "Unexpected path not under $HOME";
    return;
  }

  // Coalesce these calls if we have one pending.
  if (file_watch_change_posted_.count(path) > 0) {
    return;
  }

  // Send right away if it has been long enough since the last one, else post
  // delayed task.
  base::TimeDelta time_since_last =
      base::TimeTicks::Now() - file_watch_last_change_[path];
  if (time_since_last > kFilesystemChangeCoalesceTime) {
    SendFileWatchTriggeredToHost(path);
  } else {
    task_runner_->PostDelayedTask(
        FROM_HERE,
        base::Bind(&HostNotifier::SendFileWatchTriggeredToHost,
                   base::Unretained(this), path),
        kFilesystemChangeCoalesceTime - time_since_last);
    file_watch_change_posted_.insert(path);
  }
}

}  // namespace garcon
}  // namespace vm_tools
