/*
 * 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"});
    if (HostArch() == "aarch64") {
      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
