// 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 UartDriver>
  constexpr bool operator()(const uart::all::Config<UartDriver>& value,
                            const uart::all::Config<UartDriver>& init) const {
    bool are_equal = false;
    value.Visit([&]<typename Driver1>(const uart::Config<Driver1>& dcfg_1) {
      init.Visit([&]<typename Driver2>(const uart::Config<Driver2>& dcfg_2) {
        are_equal = dcfg_1 == dcfg_2;
      });
    });
    return are_equal;
  }
};

template <typename T>
void WriteJsonOption(rapidjson::PrettyWriter<rapidjson::FileWriteStream>& writer, const char* name,
                     const char* type, const char* member, std::string_view doc,
                     std::optional<std::string_view> init_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()));

  if (init_doc) {
    writer.Key("default_description");
    writer.String(init_doc->data(), static_cast<rapidjson::SizeType>(init_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, {__VA_ARGS__}, 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();

  writer.Key("riscv64");
  writer.StartArray();
#include <lib/boot-options/riscv64.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;
}
