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

#include "host/libs/config/kernel_args.h"

#include <array>
#include <sstream>
#include <string>
#include <vector>

#include "common/libs/utils/environment.h"
#include "common/libs/utils/files.h"
#include "host/libs/config/cuttlefish_config.h"
#include "host/libs/vm_manager/qemu_manager.h"
#include "host/libs/vm_manager/vm_manager.h"

namespace cuttlefish {

using vm_manager::QemuManager;

namespace {

template<typename T>
void AppendVector(std::vector<T>* destination, const std::vector<T>& source) {
  destination->insert(destination->end(), source.begin(), source.end());
}

// TODO(schuffelen): Move more of this into host/libs/vm_manager, as a
// substitute for the vm_manager comparisons.
std::vector<std::string> VmManagerKernelCmdline(const CuttlefishConfig& config) {
  std::vector<std::string> vm_manager_cmdline;
  if (config.vm_manager() == QemuManager::name() || config.use_bootloader()) {
    // crosvm sets up the console= earlycon= panic= flags for us if booting straight to
    // the kernel, but QEMU and the bootloader via crosvm does not.
    AppendVector(&vm_manager_cmdline, {"console=hvc0", "panic=-1"});
    Arch target_arch = config.target_arch();
    if (target_arch == Arch::Arm64 || target_arch == Arch::Arm) {
      if (config.vm_manager() == QemuManager::name()) {
        // To update the pl011 address:
        // $ qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine dumpdtb=virt.dtb
        // $ dtc -O dts -o virt.dts -I dtb virt.dtb
        // In the virt.dts file, look for a uart node
        vm_manager_cmdline.push_back(" earlycon=pl011,mmio32,0x9000000");
      } else {
        // Crosvm ARM only supports earlycon uart over mmio.
        vm_manager_cmdline.push_back(" earlycon=uart8250,mmio,0x3f8");
      }
    } else {
      // To update the uart8250 address:
      // $ qemu-system-x86_64 -kernel bzImage -serial stdio | grep ttyS0
      // Only 'io' mode works; mmio and mmio32 do not
      vm_manager_cmdline.push_back("earlycon=uart8250,io,0x3f8");

      if (config.vm_manager() == QemuManager::name()) {
        // crosvm doesn't support ACPI PNP, but QEMU does. We need to disable
        // it on QEMU so that the ISA serial ports aren't claimed by ACPI, so
        // we can use serdev with platform devices instead
        vm_manager_cmdline.push_back("pnpacpi=off");

        // crosvm sets up the ramoops.xx= flags for us, but QEMU does not.
        // See external/crosvm/x86_64/src/lib.rs
        // this feature is not supported on aarch64
        vm_manager_cmdline.push_back("ramoops.mem_address=0x100000000");
        vm_manager_cmdline.push_back("ramoops.mem_size=0x200000");
        vm_manager_cmdline.push_back("ramoops.console_size=0x80000");
        vm_manager_cmdline.push_back("ramoops.record_size=0x80000");
        vm_manager_cmdline.push_back("ramoops.dump_oops=1");
      } else {
        // crosvm requires these additional parameters on x86_64 in bootloader mode
        AppendVector(&vm_manager_cmdline, {"pci=noacpi", "reboot=k"});
      }
    }
  }

  if (config.console() && config.kgdb()) {
    AppendVector(&vm_manager_cmdline, {"kgdboc_earlycon", "kgdbcon",
                                       "kgdboc=" + config.console_dev()});
  }
  return vm_manager_cmdline;
}

} // namespace

std::vector<std::string> KernelCommandLineFromConfig(
    const CuttlefishConfig& config) {
  std::vector<std::string> kernel_cmdline;

  AppendVector(&kernel_cmdline, VmManagerKernelCmdline(config));

  if (config.enable_gnss_grpc_proxy()) {
    kernel_cmdline.push_back("gnss_cmdline.serdev=serial8250/serial0/serial0-0");
    kernel_cmdline.push_back("gnss_cmdline.type=0");
    kernel_cmdline.push_back("serdev_ttyport.pdev_tty_port=ttyS1");
  }

  if (config.guest_audit_security()) {
    kernel_cmdline.push_back("audit=1");
  } else {
    kernel_cmdline.push_back("audit=0");
  }

  AppendVector(&kernel_cmdline, config.extra_kernel_cmdline());

  return kernel_cmdline;
}

} // namespace cuttlefish
