/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#include <libxml/tree.h>
#include <memory>

namespace config {
// GuestConfig builds XML document describing target VM.
// Documents built by GuestConfig can be directly used by libvirt to instantiate
// new virtual machine.
class GuestConfig {
 public:
  GuestConfig() = default;
  ~GuestConfig() = default;

  // Set instance ID.
  GuestConfig& SetID(int id) {
    id_ = id;
    return *this;
  }

  // Set number of virtual CPUs.
  GuestConfig& SetVCPUs(int vcpus) {
    vcpus_ = vcpus;
    return *this;
  }

  // Set total memory amount it MB.
  GuestConfig& SetMemoryMB(int mem_mb) {
    memory_mb_ = mem_mb;
    return *this;
  }

  // Set kernel path.
  GuestConfig& SetKernelName(const std::string& kernel) {
    kernel_name_ = kernel;
    return *this;
  }

  // Set kernel cmdline arguments.
  GuestConfig& SetKernelArgs(const std::string& args) {
    kernel_args_ = args;
    return *this;
  }

  // Set initrd path.
  GuestConfig& SetInitRDName(const std::string& initrd) {
    initrd_name_ = initrd;
    return *this;
  }

  // Set Android system partition image path.
  GuestConfig& SetSystemPartitionPath(const std::string& path) {
    system_partition_path_ = path;
    return *this;
  }

  // Set Android data partition image path.
  GuestConfig& SetCachePartitionPath(const std::string& path) {
    cache_partition_path_ = path;
    return *this;
  }

  // Set Android data partition image path.
  GuestConfig& SetDataPartitionPath(const std::string& path) {
    data_partition_path_ = path;
    return *this;
  }

  // Set Android vendor partition image path.
  GuestConfig& SetVendorPartitionPath(const std::string& path) {
    vendor_partition_path_ = path;
    return *this;
  }

  // Set ivshmem server socket path.
  GuestConfig& SetIVShMemSocketPath(const std::string& path) {
    ivshmem_socket_path_ = path;
    return *this;
  }

  // Set number of vectors supplied by ivserver.
  GuestConfig& SetIVShMemVectorCount(int count) {
    ivshmem_vector_count_ = count;
    return *this;
  }

  // Set name of the mobile bridge, eg. br0
  GuestConfig& SetMobileBridgeName(const std::string& name) {
    mobile_bridge_name_ = name;
    return *this;
  }

  // Set source of entropy, eg. /dev/urandom.
  GuestConfig& SetEntropySource(const std::string& source) {
    entropy_source_ = source;
    return *this;
  }

  // Set emulator that will be used to start vm, eg. /usr/bin/qemu
  GuestConfig& SetEmulator(const std::string& emulator) {
    emulator_ = emulator;
    return *this;
  }

  // GetInstanceName returns name of this newly created instance.
  std::string GetInstanceName() const;

  // GetUSBSocketName returns name of the USB socket that will be used to
  // forward access to USB gadget.
  std::string GetUSBSocketName() const;

  // Build document as formatted XML string.
  std::string Build() const;

 private:
  int id_;
  int vcpus_;
  int memory_mb_;

  std::string kernel_name_;
  std::string kernel_args_;
  std::string initrd_name_;

  std::string system_partition_path_;
  std::string cache_partition_path_;
  std::string data_partition_path_;
  std::string vendor_partition_path_;

  std::string ivshmem_socket_path_;
  int ivshmem_vector_count_;

  std::string mobile_bridge_name_;
  std::string entropy_source_;

  std::string emulator_;

  GuestConfig(const GuestConfig&) = delete;
  GuestConfig& operator=(const GuestConfig&) = delete;
};

}  // namespace config
