/*
 * 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, {"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
