// 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.

#ifndef VM_TOOLS_CICERONE_SERVICE_H_
#define VM_TOOLS_CICERONE_SERVICE_H_

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

#include <base/callback.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_path.h>
#include <base/files/file_path_watcher.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <base/optional.h>
#include <base/sequence_checker.h>
#include <base/threading/thread.h>
#include <brillo/process/process.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include <grpcpp/grpcpp.h>
#include <vm_applications/proto_bindings/apps.pb.h>
#include <vm_cicerone/proto_bindings/cicerone_service.pb.h>
#include <vm_concierge/proto_bindings/concierge_service.pb.h>
#include <chromeos/dbus/service_constants.h>

#include "vm_tools/cicerone/container.h"
#include "vm_tools/cicerone/container_listener_impl.h"
#include "vm_tools/cicerone/crash_listener_impl.h"
#include "vm_tools/cicerone/shill_client.h"
#include "vm_tools/cicerone/tremplin_listener_impl.h"
#include "vm_tools/cicerone/virtual_machine.h"

namespace vm_tools {
namespace cicerone {

// VM Container Service responsible for responding to DBus method calls for
// interacting with VM containers.
class Service final {
 public:
  // Creates a new Service instance.  |quit_closure| is posted to the TaskRunner
  // for the current thread when this process receives a SIGTERM. |bus| is a
  // connection to the SYSTEM dbus.
  // Normally, services are bound to a AF_VSOCK and AF_UNIX socket. For unit
  // tests, the services only listen on an AF_UNIX socket by giving
  // |unix_socket_path_for_testing| a value.
  static std::unique_ptr<Service> Create(
      base::Closure quit_closure,
      const base::Optional<base::FilePath>& unix_socket_path_for_testing,
      scoped_refptr<dbus::Bus> bus);

  ~Service();

  ContainerListenerImpl* GetContainerListenerImpl() const {
    return container_listener_.get();
  }

  TremplinListenerImpl* GetTremplinListenerImpl() const {
    return tremplin_listener_.get();
  }

  CrashListenerImpl* GetCrashListenerImpl() const {
    return crash_listener_.get();
  }

  // For testing only. Pretend that the Tremplin server for the given VM is
  // actually at |tremplin_address| instead of the normal vsock address. Must
  // be called after the VM is created but before the corresponding
  // ConnectTremplin is called.
  bool SetTremplinStubOfVmForTesting(
      const std::string& owner_id,
      const std::string& vm_name,
      std::unique_ptr<vm_tools::tremplin::Tremplin::StubInterface>
          mock_tremplin_stub);

  // For testing only. Force the given VM to add a container with the indicated
  // security token. A VM with |owner_id|, |vm_name| must already exist. This is
  // the only way to get a consistent security token for unit tests & fuzz
  // tests. Returns true on success.
  bool CreateContainerWithTokenForTesting(const std::string& owner_id,
                                          const std::string& vm_name,
                                          const std::string& container_name,
                                          const std::string& container_token);

  // Stop Service from starting GRPC servers in a testing environment. Must
  // be called before calling Service::Init (and therefore Service::Create).
  static void DisableGrpcForTesting();

  // Connect to the Tremplin instance on the VM with the given |cid|.
  void ConnectTremplin(const uint32_t cid,
                       bool* result,
                       base::WaitableEvent* event);

  // The status of an ongoing LXD container create operation.
  enum class CreateStatus {
    UNKNOWN,
    CREATED,
    DOWNLOAD_TIMED_OUT,
    CANCELLED,
    FAILED,
  };

  // The status of an ongoing LXD container start operation.
  enum class StartStatus {
    UNKNOWN,
    STARTED,
    CANCELLED,
    FAILED,
  };

  // Notifies the service that a VM with |cid| has finished its create
  // operation of |container_name| with |status|. |failure_reason| will describe
  // the failure reason if status != CREATED. Sets |result| to true if the VM
  // cid is known. Signals |event| when done.
  void LxdContainerCreated(const uint32_t cid,
                           std::string container_name,
                           CreateStatus status,
                           std::string failure_reason,
                           bool* result,
                           base::WaitableEvent* event);

  // Notifies the service that a VM with |cid| is downloading a container
  // |container_name| with |download_progress| percentage complete. Sets
  // |result| to true if the VM cid is known. Signals |event| when done.
  void LxdContainerDownloading(const uint32_t cid,
                               std::string container_name,
                               int download_progress,
                               bool* result,
                               base::WaitableEvent* event);

  // Notifies the service that a VM with |cid| has finished its delete
  // operation of |container_name| with |status|. |failure_reason| will describe
  // the failure reason if status != DELETED. Sets |result| to true if the VM
  // cid is known. Signals |event| when done.
  void LxdContainerDeleted(
      const uint32_t cid,
      std::string container_name,
      vm_tools::tremplin::ContainerDeletionProgress::Status status,
      std::string failure_reason,
      bool* result,
      base::WaitableEvent* event);

  // Notifies the service that a VM with |cid| is starting a container
  // |container_name| with status |status|. |failure_reason| will describe the
  // failure reason if status == FAILED. Sets |result| to true if the VM cid
  // is known. Signals |event| when done.
  void LxdContainerStarting(const uint32_t cid,
                            std::string container_name,
                            StartStatus status,
                            std::string failure_reason,
                            bool* result,
                            base::WaitableEvent* event);

  // Notifies the service that a container with |container_token| and running
  // in a VM |cid| has completed startup. Sets |result| to true if this maps to
  // a currently running VM and |container_token| matches a security token for
  // that VM; false otherwise. Signals |event| when done.
  void ContainerStartupCompleted(const std::string& container_token,
                                 const uint32_t cid,
                                 const uint32_t garcon_vsock_port,
                                 bool* result,
                                 base::WaitableEvent* event);

  // Notifies the service that a container with |container_name| or
  // |container_token| and running in a VM with |cid| is shutting down. Sets
  // |result| to true if this maps to a currently running VM and
  // |container_token| matches a security token for that VM; false otherwise.
  // Signals |event| when done.  Callers from within the VM (tremplin) may set
  // |container_name|, but callers from wihtin a container (garcon) should not
  // be trusted to use |container_name| and must use |container_token|.
  void ContainerShutdown(std::string container_name,
                         std::string container_token,
                         const uint32_t cid,
                         bool* result,
                         base::WaitableEvent* event);

  // Notifies the service of a change in |listening_tcp4_ports| for the VM with
  // |cid|. Sets |result| to true if this maps to a currently running VM; false
  // otherwise. Signals |event| when done.
  void UpdateListeningPorts(
      std::map<std::string, std::vector<uint16_t>> listening_tcp4_ports,
      const uint32_t cid,
      bool* result,
      base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners on update for the progress or
  // completion of container export. It will use |cid| to resolve the request to
  // a VM. |progress_signal| should have all related fields set |result| is set
  // to true on success, false otherwise. Signals |event| when done.
  void ContainerExportProgress(
      const uint32_t cid,
      ExportLxdContainerProgressSignal* progress_signal,
      bool* result,
      base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners on update for the progress or
  // completion of container import. It will use |cid| to resolve the request to
  // a VM. |progress_signal| should have all related fields set |result| is set
  // to true on success, false otherwise. Signals |event| when done.
  void ContainerImportProgress(
      const uint32_t cid,
      ImportLxdContainerProgressSignal* progress_signal,
      bool* result,
      base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners of progress or completion of a
  // container upgrade. It will use |cid| to resolve the request to
  // a VM. |progress_signal| should have all related fields set |result| is set
  // to true on success, false otherwise. Signals |event| when done.
  void ContainerUpgradeProgress(const uint32_t cid,
                                UpgradeContainerProgressSignal* progress_signal,
                                bool* result,
                                base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners of progress or completion of
  // starting lxd. It will use |cid| to resolve the request to a VM.
  // |progress_signal| should have all related fields set. |result| is set to
  // true on success, false otherwise. Signals |event| when done.
  void StartLxdProgress(const uint32_t cid,
                        StartLxdProgressSignal* progress_signal,
                        bool* result,
                        base::WaitableEvent* event);

  void PendingUpdateApplicationListCalls(const std::string& container_token,
                                         const uint32_t cid,
                                         const uint32_t count,
                                         bool* result,
                                         base::WaitableEvent* event);

  // This will send a D-Bus message to Chrome to inform it of the current
  // installed application list for a container. It will use |cid| to
  // resolve the request to a VM and then |container_token| to resolve it to a
  // container. |app_list| should be populated with the list of installed
  // applications but the vm & container names should be left blank; it must
  // remain valid for the lifetime of this call. |result| is set to true on
  // success, false otherwise. Signals |event| when done.
  void UpdateApplicationList(const std::string& container_token,
                             const uint32_t cid,
                             vm_tools::apps::ApplicationList* app_list,
                             bool* result,
                             base::WaitableEvent* event);

  // Sends a D-Bus message to Chrome to tell it to open the |url| in a new tab.
  // |result| is set to true on success, false otherwise. Signals
  // |event| when done.
  void OpenUrl(const std::string& container_token,
               const std::string& url,
               uint32_t cid,
               bool* result,
               base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners on update for the progress or
  // completion of a Linux package install. It will use |cid| to
  // resolve the request to a VM and then |container_token| to resolve it to a
  // container. |progress_signal| should have all related fields from the
  // container request set in it. |result| is set to true on success, false
  // otherwise. Signals |event| when done.
  void InstallLinuxPackageProgress(
      const std::string& container_token,
      const uint32_t cid,
      InstallLinuxPackageProgressSignal* progress_signal,
      bool* result,
      base::WaitableEvent* event);

  // Sends a D-Bus signal to inform Chrome about the progress or completion of a
  // Linux package uninstall. It will use |cid| to resolve the request to a VM
  // and then |container_token| to resolve it to a container. |progress_signal|
  // should have all related fields from the container request set in it.
  // |result| is set to true on success, false otherwise. Signals |event| when
  // done.
  void UninstallPackageProgress(const std::string& container_token,
                                const uint32_t cid,
                                UninstallPackageProgressSignal* progress_signal,
                                bool* result,
                                base::WaitableEvent* event);

  // Sends a D-Bus signal to inform listeners on update for the progress or
  // completion of a Ansible playbook application. It will use |cid| to
  // resolve the request to a VM and then |container_token| to resolve it to a
  // container. |progress_signal| should have all related fields from the
  // container request set in it. |result| is set to true on success, false
  // otherwise. Signals |event| when done.
  void ApplyAnsiblePlaybookProgress(
      const std::string& container_token,
      const uint32_t cid,
      ApplyAnsiblePlaybookProgressSignal* progress_signal,
      bool* result,
      base::WaitableEvent* event);

  // Sends a D-Bus message to Chrome to tell it to open a terminal that is
  // connected back to the VM/container and if there are params in
  // |terminal_params| then those should be executed in that terminal.
  // It will use |cid| to resolve the request to a VM and then
  // |container_token| to resolve it to a container.  |result| is set to true on
  // success, false otherwise. Signals |event| when done.
  void OpenTerminal(const std::string& container_token,
                    vm_tools::apps::TerminalParams terminal_params,
                    const uint32_t cid,
                    bool* result,
                    base::WaitableEvent* event);

  // Sends a D-Bus message to Chrome to update the list of file extensions to
  // MIME type mapping in the container, the mappings are contained in
  // |mime_types|. It will use |cid| to resolve the request to a VM and then
  // |container_token| to resolve it to a container.  |result| is set to true on
  // success, false otherwise. Signals |event| when done.
  void UpdateMimeTypes(const std::string& container_token,
                       vm_tools::apps::MimeTypes mime_types,
                       const uint32_t cid,
                       bool* result,
                       base::WaitableEvent* event);

  // Sends a D-Bus signal to inform that a file has changed within the watched
  // directory. It will use |cid| to resolve the request to a VM and then
  // |container_token| to resolve it to a container. |triggered_signal| should
  // have all related fields from the container request set in it. |result| is
  // set to true on success, false otherwise. Signals |event| when done.
  void FileWatchTriggered(const std::string& container_token,
                          const uint32_t cid,
                          FileWatchTriggeredSignal* triggered_signal,
                          bool* result,
                          base::WaitableEvent* event);

  // Gets the VirtualMachine that corresponds to a container at |cid|
  // or the |vm_token| for the VM itself and sets |vm_out| to the
  // VirtualMachine, |owner_id_out| to the owner id of the VM, and |name_out| to
  // the name of the VM. Returns false if no such mapping exists.
  bool GetVirtualMachineForCidOrToken(const uint32_t cid,
                                      const std::string& vm_token,
                                      VirtualMachine** vm_out,
                                      std::string* owner_id_out,
                                      std::string* name_out);

 private:
  // Sends the |signal_name| D-Bus signal with |signal_proto| as its contents.
  // It will use |cid| to lookup VM and owner, and set these fields on
  // |signal_proto| before sending it.
  template <typename T>
  bool SendSignal(const std::string& signal_name,
                  const uint32_t cid,
                  T* signal_proto) {
    DCHECK(sequence_checker_.CalledOnValidSequence());
    CHECK(signal_proto);
    VirtualMachine* vm;
    std::string owner_id;
    std::string vm_name;

    if (!GetVirtualMachineForCidOrToken(cid, "", &vm, &owner_id, &vm_name)) {
      LOG(ERROR) << "Could not get virtual machine for cid";
      return false;
    }

    dbus::Signal signal(kVmCiceroneInterface, signal_name);
    signal_proto->set_vm_name(std::move(vm_name));
    signal_proto->set_owner_id(std::move(owner_id));
    dbus::MessageWriter(&signal).AppendProtoAsArrayOfBytes(*signal_proto);
    exported_object_->SendSignal(&signal);
    return true;
  }

  // Sends the |signal_name| D-Bus signal with |signal_proto| as its contents.
  // It will use |cid| and |container_token| to lookup VM, owner, and container
  // name, and set these fields on |signal_proto| before sending it.
  template <typename T>
  bool SendSignal(const std::string& signal_name,
                  const std::string& container_token,
                  const uint32_t cid,
                  T* signal_proto) {
    DCHECK(sequence_checker_.CalledOnValidSequence());
    CHECK(signal_proto);
    VirtualMachine* vm;
    std::string owner_id;
    std::string vm_name;

    if (!GetVirtualMachineForCidOrToken(cid, container_token, &vm, &owner_id,
                                        &vm_name)) {
      LOG(ERROR) << "Could not get virtual machine for cid";
      return false;
    }

    std::string container_name = vm->GetContainerNameForToken(container_token);
    if (container_name.empty()) {
      LOG(ERROR) << "Could not get container name for token";
      return false;
    }

    dbus::Signal signal(kVmCiceroneInterface, signal_name);
    signal_proto->set_vm_name(std::move(vm_name));
    signal_proto->set_container_name(std::move(container_name));
    signal_proto->set_owner_id(std::move(owner_id));
    dbus::MessageWriter(&signal).AppendProtoAsArrayOfBytes(*signal_proto);
    exported_object_->SendSignal(&signal);
    return true;
  }

  explicit Service(base::Closure quit_closure, scoped_refptr<dbus::Bus> bus);

  // Initializes the service by exporting our DBus methods, taking ownership of
  // its name, and starting our gRPC servers. If |unix_socket_path_for_testing|
  // has a value, the services are bound only to an AF_UNIX socket in that
  // directory instead of the normal VSOCK and AF_UNIX socket.
  bool Init(const base::Optional<base::FilePath>& unix_socket_path_for_testing);

  // Handles the termination of a child process.
  void HandleChildExit();

  // Handles a SIGTERM.
  void HandleSigterm();

  // Handles notification a VM is starting.
  std::unique_ptr<dbus::Response> NotifyVmStarted(
      dbus::MethodCall* method_call);

  // Handles a notification a VM is stopping.
  std::unique_ptr<dbus::Response> NotifyVmStopping(
      dbus::MethodCall* method_call);

  // Handles a notification a VM has stopped.
  std::unique_ptr<dbus::Response> NotifyVmStopped(
      dbus::MethodCall* method_call);

  // Handles a request to get a security token to associate with a container.
  std::unique_ptr<dbus::Response> GetContainerToken(
      dbus::MethodCall* method_call);

  // Handles a request to launch an application in a container.
  std::unique_ptr<dbus::Response> LaunchContainerApplication(
      dbus::MethodCall* method_call);

  // Handles a request to get application icons in a container.
  std::unique_ptr<dbus::Response> GetContainerAppIcon(
      dbus::MethodCall* method_call);

  // Handles a request to launch vshd in a container.
  std::unique_ptr<dbus::Response> LaunchVshd(dbus::MethodCall* method_call);

  // Handles a request to get Linux package info from a container.
  std::unique_ptr<dbus::Response> GetLinuxPackageInfo(
      dbus::MethodCall* method_call);

  // Handles a request to install a Linux package file in a container.
  std::unique_ptr<dbus::Response> InstallLinuxPackage(
      dbus::MethodCall* method_call);

  // Handles a request to uninstall the Linux package that owns the indicated
  // .desktop file.
  std::unique_ptr<dbus::Response> UninstallPackageOwningFile(
      dbus::MethodCall* method_call);

  // Handles a request to create an LXD container.
  std::unique_ptr<dbus::Response> CreateLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to delete an LXD container.
  std::unique_ptr<dbus::Response> DeleteLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to start an LXD container.
  std::unique_ptr<dbus::Response> StartLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to set the default timezone for an LXD instance.
  std::unique_ptr<dbus::Response> SetTimezone(dbus::MethodCall* method_call);

  // Handles a request to get the primary username for an LXD container.
  std::unique_ptr<dbus::Response> GetLxdContainerUsername(
      dbus::MethodCall* method_call);

  // Handles a request to set up the user for an LXD container.
  std::unique_ptr<dbus::Response> SetUpLxdContainerUser(
      dbus::MethodCall* method_call);

  // Handles a request to export an LXD container.
  std::unique_ptr<dbus::Response> ExportLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to cancel an ongoing LXD container export.
  std::unique_ptr<dbus::Response> CancelExportLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to import an LXD container.
  std::unique_ptr<dbus::Response> ImportLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to cancel an ongoing LXD container import.
  std::unique_ptr<dbus::Response> CancelImportLxdContainer(
      dbus::MethodCall* method_call);

  // Handles a request to connect to chunnel.
  std::unique_ptr<dbus::Response> ConnectChunnel(dbus::MethodCall* method_call);

  // Handles a request to get debug information.
  std::unique_ptr<dbus::Response> GetDebugInformation(
      dbus::MethodCall* method_call);

  // Handles a request to apply Ansible playbook to a container.
  std::unique_ptr<dbus::Response> ApplyAnsiblePlaybook(
      dbus::MethodCall* method_call);

  // Handles a request to allow sideloading Arc (android) apps from the
  // container.
  std::unique_ptr<dbus::Response> ConfigureForArcSideload(
      dbus::MethodCall* method_call);

  // Handles a request to upgrade a container.
  std::unique_ptr<dbus::Response> UpgradeContainer(
      dbus::MethodCall* method_call);

  // Handles a request to cancel an ongoing container upgrade.
  std::unique_ptr<dbus::Response> CancelUpgradeContainer(
      dbus::MethodCall* method_call);

  // Handles a request to start LXD.
  std::unique_ptr<dbus::Response> StartLxd(dbus::MethodCall* method_call);

  // Handles a request to add a file watch.
  std::unique_ptr<dbus::Response> AddFileWatch(dbus::MethodCall* method_call);

  // Handles a request to remove a file watch.
  std::unique_ptr<dbus::Response> RemoveFileWatch(
      dbus::MethodCall* method_call);

  // Handles a request to add a mapping between vsh and the session data such as
  // the container shell pid.
  std::unique_ptr<dbus::Response> RegisterVshSession(
      dbus::MethodCall* method_call);

  // Handles a request to retrieve vsh session data.
  std::unique_ptr<dbus::Response> GetVshSession(dbus::MethodCall* method_call);

  // Gets the container's SSH keys from concierge.
  bool GetContainerSshKeys(const std::string& owner_id,
                           const std::string& vm_name,
                           const std::string& container_name,
                           std::string* host_pubkey_out,
                           std::string* host_privkey_out,
                           std::string* container_pubkey_out,
                           std::string* container_privkey_out,
                           std::string* hostname_out,
                           std::string* error_out);

  // Registers |hostname| and |ip| with the hostname resolver service so that
  // the container is reachable from a known hostname.
  void RegisterHostname(const std::string& hostname, const std::string& ip);

  // Unregisters containers associated with this |vm| with |owner_id| and
  // |vm_name|.  All hostnames are removed from the hostname resolver service,
  // and the ContainerShutdown signal is sent via D-Bus.
  void UnregisterVmContainers(VirtualMachine* vm,
                              const std::string& owner_id,
                              const std::string& vm_name);

  // Unregisters |hostname| with the hostname resolver service.
  void UnregisterHostname(const std::string& hostname);

  // Callback for when the crosdns D-Bus service goes online (or is online
  // already) so we can then register the NameOwnerChanged callback.
  void OnCrosDnsServiceAvailable(bool service_is_available);

  // Callback for when the crosdns D-Bus service restarts so we can
  // re-register any of our hostnames that are active.
  void OnCrosDnsNameOwnerChanged(const std::string& old_owner,
                                 const std::string& new_owner);

  // Callback for when the localtime file is changed so that we can update
  // the timezone for containers.
  void OnLocaltimeFileChanged(const base::FilePath& path, bool error);

  void OnSignalReadable();

  // Handles default service changes from shill.
  void OnDefaultNetworkServiceChanged();

  // Send all listening ports to chunneld.
  void SendListeningPorts();

  // Gets a VirtualMachine pointer to the registered VM with corresponding
  // |owner_id| and |vm_name|. Returns a nullptr if not found.
  VirtualMachine* FindVm(const std::string& owner_id,
                         const std::string& vm_name);

  // File descriptor for SIGTERM/SIGCHLD event.
  base::ScopedFD signal_fd_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;

  // The shill D-Bus client.
  std::unique_ptr<ShillClient> shill_client_;

  // Key for VMs in the map, which is the owner ID and VM name as a pair.
  using VmKey = std::pair<std::string, std::string>;
  // Running VMs.
  std::map<VmKey, std::unique_ptr<VirtualMachine>> vms_;

  // Map of TCP4 ports to forwarding targets.
  using TcpForwardTarget = std::pair<std::string, std::string>;
  std::map<uint16_t, TcpForwardTarget> listening_tcp4_ports_;

  // Connection to the system bus.
  scoped_refptr<dbus::Bus> bus_;
  dbus::ExportedObject* exported_object_;             // Owned by |bus_|.
  dbus::ObjectProxy* vm_applications_service_proxy_;  // Owned by |bus_|.
  dbus::ObjectProxy* url_handler_service_proxy_;      // Owned by |bus_|.
  dbus::ObjectProxy* chunneld_service_proxy_;         // Owned by |bus_|.
  dbus::ObjectProxy* crosdns_service_proxy_;          // Owned by |bus_|.
  dbus::ObjectProxy* concierge_service_proxy_;        // Owned by |bus_|.

  // The ContainerListener service.
  std::unique_ptr<ContainerListenerImpl> container_listener_;

  // Thread on which the ContainerListener service lives.
  base::Thread grpc_thread_container_{"gRPC Container Server Thread"};

  // The server where the ContainerListener service lives.
  std::shared_ptr<grpc::Server> grpc_server_container_;

  // The TremplinListener service.
  std::unique_ptr<TremplinListenerImpl> tremplin_listener_;

  // Thread on which the TremplinListener service lives.
  base::Thread grpc_thread_tremplin_{"gRPC Tremplin Server Thread"};

  // The server where the TremplinListener service lives.
  std::shared_ptr<grpc::Server> grpc_server_tremplin_;

  // The CrashListener service.
  std::unique_ptr<CrashListenerImpl> crash_listener_;

  // Thread on which the CrashListener service lives.
  base::Thread grpc_thread_crash_{"gRPC Crash Server Thread"};

  // The server where the CrashListener service lives.
  std::shared_ptr<grpc::Server> grpc_server_crash_;

  // Closure that's posted to the current thread's TaskRunner when the service
  // receives a SIGTERM.
  base::Closure quit_closure_;

  // Ensure calls are made on the right thread.
  base::SequenceChecker sequence_checker_;

  // Map of hostnames/IPs we have registered so we can re-register them if the
  // resolver service restarts.
  std::map<std::string, std::string> hostname_mappings_;

  // IP address registered for 'linuxhost' so we can swap this out on OpenUrl
  // calls.
  std::string linuxhost_ip_;

  // Owner of the primary VM, we only do hostname mappings for the primary VM.
  std::string primary_owner_id_;

  // Handle to the SSH port forwarding process.
  brillo::ProcessImpl ssh_process_;

  // Watcher to monitor changes to the system timezone file.
  base::FilePathWatcher localtime_watcher_;

  // Should Service start GRPC servers for ContainerListener and
  // TremplinListener Used for testing
  static bool run_grpc_;

  base::WeakPtrFactory<Service> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(Service);
};

}  // namespace cicerone
}  // namespace vm_tools

#endif  // VM_TOOLS_CICERONE_SERVICE_H_
