// Copyright 2019 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_DISK_IMAGE_H_
#define VM_TOOLS_CONCIERGE_DISK_IMAGE_H_

#include <archive.h>

#include <memory>
#include <string>
#include <vector>

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <crypto/secure_hash.h>
#include <dbus/exported_object.h>
#include <dbus/object_proxy.h>

#include <vm_concierge/proto_bindings/concierge_service.pb.h>

#include "vm_tools/common/vm_id.h"

namespace vm_tools {
namespace concierge {

class Service;

class DiskImageOperation {
 public:
  virtual ~DiskImageOperation() = default;

  // Execute next chunk of the disk operation, handling up to |io_limit| bytes.
  void Run(uint64_t io_limit);

  // Report operation progress, in 0..100 range.
  int GetProgress() const;

  const std::string& uuid() const { return uuid_; }
  DiskImageStatus status() const { return status_; }
  const std::string& failure_reason() const { return failure_reason_; }
  int64_t processed_size() const { return processed_size_; }

 protected:
  DiskImageOperation();
  DiskImageOperation(const DiskImageOperation&) = delete;
  DiskImageOperation& operator=(const DiskImageOperation&) = delete;

  // Executes up to |io_limit| bytes of disk operation.
  virtual bool ExecuteIo(uint64_t io_limit) = 0;

  // Called after all IO is done to commit the result.
  virtual void Finalize() = 0;

  void AccumulateProcessedSize(uint64_t size) { processed_size_ += size; }

  void set_status(DiskImageStatus status) { status_ = status; }
  void set_failure_reason(const std::string& reason) {
    failure_reason_ = reason;
  }
  void set_source_size(uint64_t source_size) { source_size_ = source_size; }

 private:
  // UUID assigned to the operation.
  const std::string uuid_;

  // Status of the operation.
  DiskImageStatus status_;

  // Failure reason, if any, to be communicated to the callers.
  std::string failure_reason_;

  // Size of the source of disk operation (bytes).
  uint64_t source_size_;

  // Number of bytes consumed from the source.
  uint64_t processed_size_;
};

class PluginVmCreateOperation : public DiskImageOperation {
 public:
  static std::unique_ptr<PluginVmCreateOperation> Create(
      base::ScopedFD in_fd,
      const base::FilePath& iso_dir,
      uint64_t source_size,
      const VmId vm_id,
      const std::vector<std::string> params);

 protected:
  bool ExecuteIo(uint64_t io_limit) override;
  void Finalize() override;

 private:
  PluginVmCreateOperation(base::ScopedFD in_fd,
                          uint64_t source_size,
                          const VmId vm_id_,
                          const std::vector<std::string> params);
  PluginVmCreateOperation(const PluginVmCreateOperation&) = delete;
  PluginVmCreateOperation& operator=(const PluginVmCreateOperation&) = delete;

  bool PrepareOutput(const base::FilePath& iso_dir);

  void MarkFailed(const char* msg, int error_code);

  // VM owner and name. Used when registering imported image with the
  // dispatcher.
  const VmId vm_id_;

  // Parameters that need to be passed to the Plugin VM helper when
  // creating the VM.
  const std::vector<std::string> params_;

  // File descriptor from which to fetch the source image.
  base::ScopedFD in_fd_;

  // File descriptor to where the data from source image will
  // be written to.
  base::ScopedFD out_fd_;

  // Destination directory object.
  base::ScopedTempDir output_dir_;
};

struct ArchiveReadDeleter {
  void operator()(struct archive* in) { archive_read_free(in); }
};
using ArchiveReader = std::unique_ptr<struct archive, ArchiveReadDeleter>;

struct ArchiveWriteDeleter {
  void operator()(struct archive* out) { archive_write_free(out); }
};
using ArchiveWriter = std::unique_ptr<struct archive, ArchiveWriteDeleter>;

enum class ArchiveFormat {
  ZIP,
  TAR_GZ,
};

class VmExportOperation : public DiskImageOperation {
 public:
  static std::unique_ptr<VmExportOperation> Create(
      const VmId vm_id,
      const base::FilePath disk_path,
      base::ScopedFD out_fd,
      base::ScopedFD out_digest_fd,
      ArchiveFormat out_fmt);

  ~VmExportOperation() override;

 protected:
  bool ExecuteIo(uint64_t io_limit) override;
  void Finalize() override;

 private:
  static int OutputFileOpenCallback(archive* a, void* data);
  static ssize_t OutputFileWriteCallback(archive* a,
                                         void* data,
                                         const void* buf,
                                         size_t length);
  static int OutputFileCloseCallback(archive* a, void* data);

  VmExportOperation(const VmId vm_id,
                    const base::FilePath disk_path,
                    base::ScopedFD out_fd,
                    base::ScopedFD out_digest_fd,
                    ArchiveFormat out_fmt);
  VmExportOperation(const VmExportOperation&) = delete;
  VmExportOperation& operator=(const VmExportOperation&) = delete;

  bool PrepareInput();
  bool PrepareOutput();

  void MarkFailed(const char* msg, struct archive* a);

  // Copies up to |io_limit| bytes of one file of the image.
  // Returns number of bytes read.
  uint64_t CopyEntry(uint64_t io_limit);

  // VM owner and name.
  const VmId vm_id_;

  // Path to the directory containing source image.
  const base::FilePath src_image_path_;

  // File descriptor to write the compressed image to.
  base::ScopedFD out_fd_;

  // File descriptor to write the SHA256 digest of the compressed image to.
  base::ScopedFD out_digest_fd_;

  // We are in a middle of copying an archive entry. Copying of one archive
  // entry may span several Run() invocations, depending on the size of the
  // entry.
  bool copying_data_;

  // If true, disk image is a directory potentially containing multiple files.
  // If false, disk image is a single file.
  bool image_is_directory_;

  // Source directory "archive".
  ArchiveReader in_;

  // Output archive backed by the file descriptor.
  ArchiveWriter out_;

  // Output archive format.
  ArchiveFormat out_fmt_;

  // Hasher to generate digest of the produced image.
  std::unique_ptr<crypto::SecureHash> sha256_;
};

class PluginVmImportOperation : public DiskImageOperation {
 public:
  static std::unique_ptr<PluginVmImportOperation> Create(
      base::ScopedFD in_fd,
      const base::FilePath disk_path,
      uint64_t source_size,
      const VmId vm_id,
      scoped_refptr<dbus::Bus> bus,
      dbus::ObjectProxy* vmplugin_service_proxy);

  ~PluginVmImportOperation() override;

 protected:
  bool ExecuteIo(uint64_t io_limit) override;
  void Finalize() override;

 private:
  PluginVmImportOperation(base::ScopedFD in_fd,
                          uint64_t source_size,
                          const base::FilePath disk_path,
                          const VmId vm_id_,
                          scoped_refptr<dbus::Bus> bus,
                          dbus::ObjectProxy* vmplugin_service_proxy);
  PluginVmImportOperation(const PluginVmImportOperation&) = delete;
  PluginVmImportOperation& operator=(const PluginVmImportOperation&) = delete;

  bool PrepareInput();
  bool PrepareOutput();

  void MarkFailed(const char* msg, struct archive* a);

  // Copies up to |io_limit| bytes of one archive entry of the image.
  // Returns number of bytes read.
  uint64_t CopyEntry(uint64_t io_limit);

  // Path to the directory that will contain the imported image.
  const base::FilePath dest_image_path_;

  // VM owner and name. Used when registering imported image with the
  // dispatcher.
  const VmId vm_id_;

  // Connection to the system bus.
  scoped_refptr<dbus::Bus> bus_;

  // Proxy to the dispatcher service.  Not owned.
  dbus::ObjectProxy* vmplugin_service_proxy_;

  // File descriptor from which to fetch the source image.
  base::ScopedFD in_fd_;

  // We are in a middle of copying an archive entry. Copying of one archive
  // entry may span several Run() invocations, depending on the size of the
  // entry.
  bool copying_data_;

  // Destination directory object.
  base::ScopedTempDir output_dir_;

  // Input compressed archive backed up by the file descriptor.
  ArchiveReader in_;

  // "Archive" representing output uncompressed directory.
  ArchiveWriter out_;
};

class VmResizeOperation : public DiskImageOperation {
 public:
  using ResizeCallback = base::Callback<void(const std::string& owner_id,
                                             const std::string& vm_name,
                                             StorageLocation location,
                                             uint64_t target_size,
                                             DiskImageStatus* status,
                                             std::string* failure_reason)>;

  static std::unique_ptr<VmResizeOperation> Create(
      const VmId vm_id,
      StorageLocation location,
      const base::FilePath disk_path,
      uint64_t disk_size,
      ResizeCallback start_resize_cb,
      ResizeCallback process_resize_cb);

 protected:
  bool ExecuteIo(uint64_t io_limit) override;
  void Finalize() override;

 private:
  VmResizeOperation(const VmId vm_id,
                    StorageLocation location,
                    const base::FilePath disk_path,
                    uint64_t size,
                    ResizeCallback process_resize_cb);
  VmResizeOperation(const VmResizeOperation&) = delete;
  VmResizeOperation& operator=(const VmResizeOperation&) = delete;

  ResizeCallback process_resize_cb_;

  // VM owner and name.
  const VmId vm_id_;

  StorageLocation location_;

  base::FilePath disk_path_;

  uint64_t target_size_;
};

}  // namespace concierge
}  // namespace vm_tools

#endif  // VM_TOOLS_CONCIERGE_DISK_IMAGE_H_
