// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_BOOT_OPTIONS_H_
#define ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_BOOT_OPTIONS_H_

// TODO(https://fxbug.dev/42108065): Once possible, only define this for test code.
// In any case, we do not want to include tests options when generating
// boot option documentation.
#define BOOT_OPTIONS_TESTONLY_OPTIONS !BOOT_OPTIONS_GENERATOR

#include <lib/uart/all.h>
#include <stdio.h>
#include <zircon/assert.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string_view>

#include "types.h"

#if BOOT_OPTIONS_TESTONLY_OPTIONS
#include "test-types.h"
#endif

struct BootOptions;  // Declared below.

// This points to the only instance of BootOptions that ever exists outside
// test code.  It's allocated in reserved physical memory by physboot and then
// handed off to the kernel proper.  A global by this name exists both in
// physboot with the physical address pointer and in the kernel with the
// virtual address pointer.
extern const BootOptions* gBootOptions;

struct BootOptions {
  // General string values get this done to each character.
  static constexpr char SanitizeChar(char c) {
    switch (c) {
      // Only printable ASCII characters come through as is.
      case ' ' ... '~':
        return c;

        // Other whitespace chars become ' '.
      case '\n':
      case '\r':
      case '\t':
        return ' ';

        // Anything else becomes '.'.
      default:
        return '.';
    }
  }

  // Return the length in the out buffer filled with the sanitized contents of
  // the input string.
  static size_t SanitizeString(char* out, size_t out_size, std::string_view in) {
    ZX_ASSERT(out_size >= in.size());
    return std::transform(in.begin(), in.end(), out, SanitizeChar) - out;
  }

  // This modifies the string in place even though it's const.
  static void Redact(std::string_view string) {
    if (string.empty()) {
      return;
    }
    constexpr char kRedacted = 'x';
    char* begin = const_cast<char*>(string.data());
    char* end = begin + string.size();
    std::fill(begin, end, kRedacted);
  }

  // Parse a string to an integer in C syntax.
  static std::optional<int64_t> ParseInt(std::string_view, std::string_view* rest = nullptr);

  // Split the command line into words and parse each one as an option.  This
  // can be called multiple times with separate command line fragments.  Each
  // word is processed in order and sets its corresponding member in this
  // struct, replacing any earlier option argument or the initial default.
  // If complain is set, print messages there if a key is not recognized.
  void SetMany(std::string_view cmdline, FILE* complain = nullptr);

  // Display the key, its value, and its default.
  int Show(std::string_view key, bool defaults = true, FILE* out = stdout) const;

  // Display all keys, values, and defaults.
  void Show(bool defaults = true, FILE* out = stdout) const;

  // Write out "key=value".
  template <typename T>
  static void Print(std::string_view key, const T& value, FILE* out = stdout) {
    fprintf(out, "%.*s=", static_cast<int>(key.size()), key.data());
    PrintValue(value, out);
  }

  // Overloads parse and print values of various types.
  // |Parse| returns true on successfully parsing the value.
#define OPTION_TYPE(T)                                   \
  bool Parse(std::string_view, T BootOptions::* member); \
  static void PrintValue(const T& value, FILE* out = stdout)

  OPTION_TYPE(bool);
  OPTION_TYPE(uint64_t);
  OPTION_TYPE(uint32_t);
  OPTION_TYPE(uint8_t);
  OPTION_TYPE(SmallString);
  OPTION_TYPE(RedactedHex);
  OPTION_TYPE(OomBehavior);
  OPTION_TYPE(EntropyTestSource);
  OPTION_TYPE(SerialDebugSyscalls);
  OPTION_TYPE(PageTableEvictionPolicy);
  OPTION_TYPE(RootJobBehavior);
  OPTION_TYPE(WallclockType);
  OPTION_TYPE(ScannerLruAction);
  OPTION_TYPE(CompressionStrategy);
  OPTION_TYPE(CompressionStorageStrategy);
  OPTION_TYPE(std::optional<RamReservation>);
#if BOOT_OPTIONS_TESTONLY_OPTIONS
  OPTION_TYPE(TestEnum);
  OPTION_TYPE(TestStruct);
#endif

#if BOOT_OPTIONS_GENERATOR || defined(__aarch64__)
  ARM64_OPTION_TYPES(OPTION_TYPE)
#endif

#if BOOT_OPTIONS_GENERATOR || defined(__riscv)
  RISCV64_OPTION_TYPES(OPTION_TYPE)
#endif

#if BOOT_OPTIONS_GENERATOR || defined(__x86_64__)
  X86_OPTION_TYPES(OPTION_TYPE)
#endif

  OPTION_TYPE(uart::all::Driver);

#undef OPTION_TYPE

  struct WordResult {
    std::string_view key;
    bool known = false;
  };

  // Returns true if the command-line word matches a known "key=value" or "key"
  // string.  If the value was parsable for the type of the key's member, then
  // the member was updated, else it wasn't touched (but still returns true).
  WordResult ParseWord(std::string_view);

#define DEFINE_OPTION(name, type, member, init, doc) type member init;
#include "options.inc"
#if BOOT_OPTIONS_GENERATOR
#include "arm64.inc"
#include "riscv64.inc"
#include "x86.inc"
#endif
#undef DEFINE_OPTION

  uint32_t smp_max_cpus = 0;
};

#endif  // ZIRCON_KERNEL_LIB_BOOT_OPTIONS_INCLUDE_LIB_BOOT_OPTIONS_BOOT_OPTIONS_H_
