// Copyright 2017 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_CONCIERGE_SERVICE_H_
#define VM_TOOLS_CONCIERGE_SERVICE_H_

#include <stdint.h>

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

#include <base/callback.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <base/sequence_checker.h>
#include <base/synchronization/lock.h>
#include <base/threading/thread.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include <grpcpp/grpcpp.h>

#include "base/files/file_path.h"
#include "vm_tools/common/vm_id.h"
#include "vm_tools/concierge/disk_image.h"
#include "vm_tools/concierge/power_manager_client.h"
#include "vm_tools/concierge/shill_client.h"
#include "vm_tools/concierge/startup_listener_impl.h"
#include "vm_tools/concierge/termina_vm.h"
#include "vm_tools/concierge/untrusted_vm_utils.h"
#include "vm_tools/concierge/vm_interface.h"
#include "vm_tools/concierge/vsock_cid_pool.h"

namespace vm_tools {
namespace concierge {

class DlcHelper;

// Used to represent kernel version.
using KernelVersionAndMajorRevision = std::pair<int, int>;

// VM Launcher Service responsible for responding to DBus method calls for
// starting, stopping, and otherwise managing VMs.
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.
  static std::unique_ptr<Service> Create(base::Closure quit_closure);
  ~Service();

 private:
  // Describes key components of a VM.
  struct VMImageSpec {
    base::FilePath kernel;
    base::FilePath initrd;
    base::FilePath rootfs;
    base::FilePath tools_disk;
    bool is_trusted_image;

    VMImageSpec() = default;
  };

  explicit Service(base::Closure quit_closure);
  Service(const Service&) = delete;
  Service& operator=(const Service&) = delete;

  // Initializes the service by connecting to the system DBus daemon, exporting
  // its methods, and taking ownership of it's name.
  bool Init();

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

  // Handles a SIGTERM.
  void HandleSigterm();

  // Helper function that is used by StartVm, StartPluginVm and StartArcVm
  template <class StartXXRequest>
  base::Optional<std::tuple<StartXXRequest, StartVmResponse>> StartVmHelper(
      dbus::MethodCall* method_call,
      dbus::MessageReader* reader,
      dbus::MessageWriter* writer,
      bool allow_zero_cpus = false);

  // Handles a request to start a VM.  |method_call| must have a StartVmRequest
  // protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> StartVm(dbus::MethodCall* method_call);

  // Handles a request to start a plugin-based VM.  |method_call| must have a
  // StartPluginVmRequest protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> StartPluginVm(dbus::MethodCall* method_call);

  // Handles a request to start ARCVM.  |method_call| must have a
  // StartArcVmRequest protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> StartArcVm(dbus::MethodCall* method_call);

  // Handles a request to stop a VM.  |method_call| must have a StopVmRequest
  // protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> StopVm(dbus::MethodCall* method_call);

  // Handles a request to suspend a VM.  |method_call| must have a
  // SuspendVmRequest protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> SuspendVm(dbus::MethodCall* method_call);

  // Handles a request to resume a VM.  |method_call| must have a
  // ResumeVmRequest protobuf serialized as an array of bytes.
  std::unique_ptr<dbus::Response> ResumeVm(dbus::MethodCall* method_call);

  // Handles a request to stop all running VMs.
  void StopAllVmsImpl();
  std::unique_ptr<dbus::Response> StopAllVms(dbus::MethodCall* method_call);

  // Handles a request to get VM info.
  std::unique_ptr<dbus::Response> GetVmInfo(dbus::MethodCall* method_call);

  // Handles a request to get VM info specific to enterprise reporting.
  std::unique_ptr<dbus::Response> GetVmEnterpriseReportingInfo(
      dbus::MethodCall* method_call);

  // Handles a request to update all VMs' times to the current host time.
  std::unique_ptr<dbus::Response> SyncVmTimes(dbus::MethodCall* method_call);

  // Handles a request to create a disk image.
  std::unique_ptr<dbus::Response> CreateDiskImage(
      dbus::MethodCall* method_call);

  // Handles a request to destroy a disk image.
  std::unique_ptr<dbus::Response> DestroyDiskImage(
      dbus::MethodCall* method_call);

  // Handles a request to resize a disk image.
  std::unique_ptr<dbus::Response> ResizeDiskImage(
      dbus::MethodCall* method_call);

  // Handles a request to get disk resize status.
  std::unique_ptr<dbus::Response> GetDiskResizeStatus(
      dbus::MethodCall* method_call);

  // Handles a request to export a disk image.
  std::unique_ptr<dbus::Response> ExportDiskImage(
      dbus::MethodCall* method_call);

  // Handles a request to import a disk image.
  std::unique_ptr<dbus::Response> ImportDiskImage(
      dbus::MethodCall* method_call);

  // Handles a request to check status of a disk image operation.
  std::unique_ptr<dbus::Response> CheckDiskImageStatus(
      dbus::MethodCall* method_call);

  // Handles a request to cancel a disk image operation.
  std::unique_ptr<dbus::Response> CancelDiskImageOperation(
      dbus::MethodCall* method_call);

  // Run import/export disk image operation with given UUID.
  void RunDiskImageOperation(std::string uuid);

  // Handles a request to list existing disk images.
  std::unique_ptr<dbus::Response> ListVmDisks(dbus::MethodCall* method_call);

  // Handles a request to get the SSH keys for a container.
  std::unique_ptr<dbus::Response> GetContainerSshKeys(
      dbus::MethodCall* method_call);

  std::unique_ptr<dbus::Response> AttachUsbDevice(
      dbus::MethodCall* method_call);

  std::unique_ptr<dbus::Response> DetachUsbDevice(
      dbus::MethodCall* method_call);

  std::unique_ptr<dbus::Response> ListUsbDevices(dbus::MethodCall* method_call);

  std::unique_ptr<dbus::Response> GetDnsSettings(dbus::MethodCall* method_call);

  std::unique_ptr<dbus::Response> SetVmCpuRestriction(
      dbus::MethodCall* method_call);

  // Handles a request to adjust parameters of a given VM.
  std::unique_ptr<dbus::Response> AdjustVm(dbus::MethodCall* method_call);

  // Handles a request to set the owner id of a given VM.
  std::unique_ptr<dbus::Response> SetVmId(dbus::MethodCall* method_call);

  // Writes DnsConfigResponse protobuf into DBus message.
  void ComposeDnsResponse(dbus::MessageWriter* writer);

  // Handles DNS changes from shill.
  void OnResolvConfigChanged(std::vector<std::string> nameservers,
                             std::vector<std::string> search_domains);

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

  // Helper for starting termina VMs, e.g. starting lxd.
  bool StartTermina(TerminaVm* vm,
                    bool allow_privileged_containers,
                    std::string* failure_reason,
                    vm_tools::StartTerminaResponse::MountResult* result);

  // Helpers for notifying cicerone and sending signals of VM started/stopped
  // events, and generating container tokens.
  void NotifyCiceroneOfVmStarted(const VmId& vm_id,
                                 uint32_t vsock_cid,
                                 pid_t pid,
                                 std::string vm_token);
  void SendVmStartedSignal(const VmId& vm_id,
                           const vm_tools::concierge::VmInfo& vm_info,
                           vm_tools::concierge::VmStatus status);
  void SendVmStartingUpSignal(const VmId& vm_id,
                              const vm_tools::concierge::VmInfo& vm_info);
  void NotifyVmStopping(const VmId& vm_id, int64_t cid);
  void NotifyVmStopped(const VmId& vm_id, int64_t cid);
  void SendVmIdChangedSignal(const VmId& id, const VmId& prev_id, int64_t cid);

  std::string GetContainerToken(const VmId& vm_id,
                                const std::string& container_name);

  void OnTremplinStartedSignal(dbus::Signal* signal);
  void OnVmToolsStateChangedSignal(dbus::Signal* signal);

  void OnSignalConnected(const std::string& interface_name,
                         const std::string& signal_name,
                         bool is_connected);
  void OnSignalReadable();

  // Called by |power_manager_client_| when the device is about to suspend or
  // resumed from suspend.
  void HandleSuspendImminent();
  void HandleSuspendDone();

  // Initiate a disk resize request for the VM identified by |owner_id| and
  // |vm_name|.
  void ResizeDisk(const std::string& owner_id,
                  const std::string& vm_name,
                  StorageLocation location,
                  uint64_t new_size,
                  DiskImageStatus* status,
                  std::string* failure_reason);
  // Query the status of the most recent ResizeDisk request.
  // If this returns DISK_STATUS_FAILED, |failure_reason| will be filled with an
  // error message.
  void ProcessResize(const std::string& owner_id,
                     const std::string& vm_name,
                     StorageLocation location,
                     uint64_t target_size,
                     DiskImageStatus* status,
                     std::string* failure_reason);

  // Finalize the resize process after a success resize has completed.
  void FinishResize(const std::string& owner_id,
                    const std::string& vm_name,
                    StorageLocation location,
                    DiskImageStatus* status,
                    std::string* failure_reason);

  // Executes rename operation of a Plugin VM.
  bool RenamePluginVm(const std::string& owner_id,
                      const std::string& old_name,
                      const std::string& new_name,
                      std::string* failure_reason);

  using VmMap = std::map<VmId, std::unique_ptr<VmInterface>>;

  // Returns an iterator to vm with key (|owner_id|, |vm_name|). If no such
  // element exists, tries the former with |owner_id| equal to empty string.
  VmMap::iterator FindVm(const std::string& owner_id,
                         const std::string& vm_name);

  bool ListVmDisksInLocation(const std::string& cryptohome_id,
                             StorageLocation location,
                             const std::string& lookup_name,
                             ListVmDisksResponse* response);

  // Determine the path for a VM image based on |dlc_id| (or the component, if
  // the id is empty). Returns the empty path and sets failure_reason in the
  // event of a failure.
  base::FilePath GetVmImagePath(const std::string& dlc_id,
                                std::string* failure_reason);

  // Determines key components of a VM image. Also, decides if it's a trusted
  // VM. Returns the empty struct and sets |failure_reason| in the event of a
  // failure.
  Service::VMImageSpec GetImageSpec(
      const vm_tools::concierge::VirtualMachineSpec& vm,
      const base::Optional<base::ScopedFD>& kernel_fd,
      const base::Optional<base::ScopedFD>& rootfs_fd,
      bool is_termina,
      std::string* failure_reason);

  // Prepares the GPU shader disk cache directory and if necessary erases
  // old caches for all VMs. Returns the prepared path.
  base::FilePath PrepareVmGpuCachePath(const std::string& owner_id,
                                       const std::string& vm_name);

  // Resource allocators for VMs.
  VsockCidPool vsock_cid_pool_;

  // Current DNS resolution config.
  std::vector<std::string> nameservers_;
  std::vector<std::string> search_domains_;

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

  // Connection to the system bus.
  base::Thread dbus_thread_{"dbus thread"};
  scoped_refptr<dbus::Bus> bus_;
  dbus::ExportedObject* exported_object_;           // Owned by |bus_|.
  dbus::ObjectProxy* cicerone_service_proxy_;       // Owned by |bus_|.
  dbus::ObjectProxy* seneschal_service_proxy_;      // Owned by |bus_|.
  dbus::ObjectProxy* vm_permission_service_proxy_;  // Owned by |bus_|.
  dbus::ObjectProxy* vmplugin_service_proxy_;       // Owned by |bus_|.

  // The port number to assign to the next shared directory server.
  uint32_t next_seneschal_server_port_;

  // Active VMs keyed by VmId which is (owner_id, vm_name).
  VmMap vms_;

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

  // The power manager D-Bus client.
  std::unique_ptr<PowerManagerClient> power_manager_client_;

  // The dlcservice helper D-Bus client.
  std::unique_ptr<DlcHelper> dlcservice_client_;

  // The StartupListener service.
  StartupListenerImpl startup_listener_;

  // Thread on which the StartupListener service lives.
  base::Thread grpc_thread_vm_{"gRPC VM Server Thread"};

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

  // 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_;

  // Signal must be connected before we can call SetTremplinStarted in a VM.
  bool is_tremplin_started_signal_connected_ = false;

  // List of currently executing operations to import/export disk images.
  struct DiskOpInfo {
    std::unique_ptr<DiskImageOperation> op;
    bool canceled;
    base::TimeTicks last_report_time;

    explicit DiskOpInfo(std::unique_ptr<DiskImageOperation> disk_op)
        : op(std::move(disk_op)),
          canceled(false),
          last_report_time(base::TimeTicks::Now()) {}
  };
  std::list<DiskOpInfo> disk_image_ops_;

  // The kernel version of the host.
  const KernelVersionAndMajorRevision host_kernel_version_;

  // Used to check for, and possibly enable, the conditions required for
  // untrusted VMs.
  std::unique_ptr<UntrustedVMUtils> untrusted_vm_utils_;

  base::WeakPtrFactory<Service> weak_ptr_factory_;

  // Used to serialize erasing and creating the GPU shader disk cache in the
  // event that VMs are started simultaneously from multiple threads.
  base::Lock cache_mutex_;
};

}  // namespace concierge
}  // namespace vm_tools

#endif  // VM_TOOLS_CONCIERGE_SERVICE_H_
