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

#include <getopt.h>
#include <lib/boot-options/boot-options.h>

#include <cstdio>
#include <cstdlib>
#include <type_traits>
#include <variant>

#include <rapidjson/document.h>
#include <rapidjson/filewritestream.h>
#include <rapidjson/prettywriter.h>

namespace {

#include "enum.h"

constexpr char kOptString[] = "j:ds:t::";
constexpr option kOptions[] = {
    {"defaults", optional_argument, nullptr, 'd'},
    {"json", required_argument, nullptr, 'j'},
    {"set", required_argument, nullptr, 's'},
    {"show", optional_argument, nullptr, 't'},
    {},
};

void usage(const char* progname) {
  fprintf(stderr, R"""(
Usage: %s OPTIONS...

  --defaults, -d              display all default values
  --json=FILE, -j FILE        write JSON description to FILE
  --set=CMDLINE, -s CMDLINE   set values from CMDLINE
  --show[=KEY], -t[KEY]       display KEY=VALUE (or all keys)

Each option is processed in turn.  Thus earlier --set options affect the output
of later --show or --json options.
)""",
          progname);
  exit(EXIT_FAILURE);
}

template <typename T>
void WriteJsonValue(rapidjson::PrettyWriter<rapidjson::FileWriteStream>& writer, const T& value) {
  if constexpr (std::is_same_v<T, bool>) {
    writer.Bool(value);
  } else if constexpr (std::is_same_v<T, uint64_t>) {
    writer.Uint64(value);
  } else if constexpr (std::is_same_v<T, uint32_t>) {
    writer.Uint(value);
  } else {
    char buffer[128];
    // fmemopen is supposed to write a NUL terminator, but if no output at all
    // is sent before fclose, it might fail to.
    buffer[0] = '\0';
    FILE* f = fmemopen(buffer, sizeof(buffer), "w");
    BootOptions::PrintValue(value, f);
    fclose(f);
    writer.String(buffer);
  }
}

struct Equal {
  template <typename EqT>
  constexpr bool operator()(const EqT& value, const EqT& init) const {
    return value == init;
  }

  template <typename... V>
  constexpr bool operator()(const std::variant<V...>& value, const std::variant<V...>& init) const {
    constexpr auto equal = [](const auto& value, const auto& init) {
      if constexpr (std::is_same_v<decltype(value), decltype(init)>) {
        return value == init;
      }
      return false;
    };
    return std::visit(equal, value, init);
  }
};

template <typename T>
void WriteJsonOption(rapidjson::PrettyWriter<rapidjson::FileWriteStream>& writer, const char* name,
                     const char* type, const char* member, std::string_view doc, const T& init,
                     const T& value) {
  writer.StartObject();

  writer.Key("name");
  writer.String(name);

  writer.Key("type");
  if constexpr (std::is_enum_v<T>) {
    writer.StartArray();
    Enum<T>(EnumEnumerator{[&writer](std::string_view name) {
                             writer.String(name.data(),
                                           static_cast<rapidjson::SizeType>(name.size()));
                           },
                           T{}});
    writer.EndArray();
  } else {
    writer.String(type);
  }

  // options.inc uses R"""(...)""" with line breaks at the start and end.
  ZX_ASSERT(doc.substr(0, 1) == "\n");
  doc.remove_prefix(1);
  ZX_ASSERT(doc.substr(doc.size() - 1) == "\n");
  doc.remove_suffix(1);

  writer.Key("documentation");
  writer.String(doc.data(), static_cast<rapidjson::SizeType>(doc.size()));

  writer.Key("default");
  WriteJsonValue<T>(writer, init);

  if (!Equal{}(value, init)) {
    writer.Key("value");
    WriteJsonValue<T>(writer, value);
  }

  writer.EndObject();
}

void WriteJson(const BootOptions& options, const char* json_output) {
  auto f = fopen(json_output, "w");
  if (!f) {
    perror(json_output);
    exit(1);
  }

  char buffer[BUFSIZ];
  rapidjson::FileWriteStream os(f, buffer, sizeof(buffer));
  rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);

  writer.StartObject();
#define DEFINE_OPTION(name, type, member, init, doc) \
  WriteJsonOption<type>(writer, name, #type, #member, doc, type init, options.member);

  writer.Key("common");
  writer.StartArray();
#include <lib/boot-options/options.inc>
  writer.EndArray();

  writer.Key("x86");
  writer.StartArray();
#include <lib/boot-options/x86.inc>
  writer.EndArray();

  writer.Key("arm64");
  writer.StartArray();
#include <lib/boot-options/arm64.inc>
  writer.EndArray();

#undef DEFINE_OPTION
  writer.EndObject();

  fclose(f);
}

}  // namespace

int main(int argc, char** argv) {
  BootOptions options;
  bool nop = true;
  int opt;
  while ((opt = getopt_long(argc, argv, kOptString, kOptions, nullptr)) != -1) {
    switch (opt) {
      case 'd':
        BootOptions{}.Show(false);
        break;

      case 'j':
        WriteJson(options, optarg);
        break;

      case 's':
        options.SetMany(optarg, stderr);
        break;

      case 't':
        if (optarg) {
          options.Show(optarg, false);
        } else {
          options.Show(false);
        }
        break;

      default:
        usage(argv[0]);
    }
    nop = false;
  }
  if (argc != optind || nop) {
    usage(argv[0]);
  }
  return 0;
}
