// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quic/platform/impl/quic_flags_impl.h"

#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <set>

#include "base/command_line.h"
#include "base/export_template.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/strcat.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/third_party/quic/platform/api/quic_logging.h"

#define QUIC_FLAG(type, flag, value) type flag = value;
#include "net/quic/quic_flags_list.h"
#include "starboard/string.h"
#undef QUIC_FLAG

namespace quic {

namespace {

// Overload for platforms where base::CommandLine::StringType == std::string.
#if defined(STARBOARD)
std::vector<QuicString>
#else
std::vector<QuicString> __attribute__((unused))
#endif
ToQuicStringVector(const std::vector<std::string>& v) {
  return v;
}

// Overload for platforms where base::CommandLine::StringType == base::string16.
#if defined(STARBOARD)
std::vector<QuicString>
#else
std::vector<QuicString> __attribute__((unused))
#endif
ToQuicStringVector(const std::vector<base::string16>& v) {
  std::vector<QuicString> qsv;
  for (const auto& s : v) {
    if (!base::IsStringASCII(s)) {
#if defined(STARBOARD)
      QUIC_LOG(ERROR) << "Unable to convert to ASCII: " << s.c_str();
#else
      QUIC_LOG(ERROR) << "Unable to convert to ASCII: " << s;
#endif
      continue;
    }
    qsv.push_back(base::UTF16ToASCII(s));
  }
  return qsv;
}

size_t FindLineWrapPosition(const std::string& s, size_t desired_len) {
  if (s.length() <= desired_len) {
    return std::string::npos;
  }
  size_t pos = s.find_last_of(base::kWhitespaceASCII, desired_len);
  if (pos != std::string::npos) {
    return pos;
  }
  pos = s.find_first_of(base::kWhitespaceASCII, desired_len);
  if (pos != std::string::npos) {
    return pos;
  }
  return std::string::npos;
}

// Pretty-print a flag description in the format:
//
// --flag_name      Some text describing the flag that can
//                  wrap around to the next line.
void AppendFlagDescription(const std::string& name,
                           std::string help,
                           std::string* out) {
  const int kStartCol = 20;
  const int kEndCol = 80;
  const int kMinPadding = 2;
  static const char kDashes[] = "--";

  base::StrAppend(out, {kDashes, name});
  int col = SbStringGetLength(kDashes) + name.length();
  if (col + kMinPadding < kEndCol) {
    // Start help text on same line
    int pad_len = std::max(kMinPadding, kStartCol - col);
    base::StrAppend(out, {std::string(pad_len, ' ')});
    col += pad_len;
  } else {
    // Start help text on next line
    base::StrAppend(out, {"\n", std::string(kStartCol, ' ')});
    col = kStartCol;
  }

  while (!help.empty()) {
    size_t desired_len = kEndCol - col;
    size_t wrap_pos = FindLineWrapPosition(help, desired_len);
    if (wrap_pos == std::string::npos) {
      base::StrAppend(out, {help});
      break;
    }
    base::StrAppend(
        out, {help.substr(0, wrap_pos), "\n", std::string(kStartCol, ' ')});
    help = help.substr(wrap_pos + 1);
    col = kStartCol;
  }
  base::StrAppend(out, {"\n"});
}

}  // namespace

// static
QuicFlagRegistry& QuicFlagRegistry::GetInstance() {
  static base::NoDestructor<QuicFlagRegistry> instance;
  return *instance;
}

void QuicFlagRegistry::RegisterFlag(const char* name,
                                    std::unique_ptr<QuicFlagHelper> helper) {
  flags_.emplace(std::string(name), std::move(helper));
}

bool QuicFlagRegistry::SetFlags(const base::CommandLine& command_line,
                                std::string* error_msg) const {
  for (const auto& kv : flags_) {
    const std::string& name = kv.first;
    const QuicFlagHelper* helper = kv.second.get();
    if (!command_line.HasSwitch(name)) {
      continue;
    }
    std::string value = command_line.GetSwitchValueASCII(name);
    if (!helper->SetFlag(value)) {
      *error_msg =
          base::StrCat({"Invalid value \"", value, "\" for flag --", name});
      return false;
    }
    QUIC_LOG(INFO) << "Set flag --" << name << " = " << value;
  }
  return true;
}

void QuicFlagRegistry::ResetFlags() const {
  for (const auto& kv : flags_) {
    kv.second->ResetFlag();
    QUIC_LOG(INFO) << "Reset flag --" << kv.first;
  }
}

std::string QuicFlagRegistry::GetHelp() const {
  std::string help;
  AppendFlagDescription("help", "Print this help message.", &help);
  for (const auto& kv : flags_) {
    AppendFlagDescription(kv.first, kv.second->GetHelp(), &help);
  }
  return help;
}

template <>
bool TypedQuicFlagHelper<bool>::SetFlag(const std::string& s) const {
  static const base::NoDestructor<std::set<std::string>> kTrueValues(
      std::initializer_list<std::string>({"", "1", "t", "true", "y", "yes"}));
  static const base::NoDestructor<std::set<std::string>> kFalseValues(
      std::initializer_list<std::string>({"0", "f", "false", "n", "no"}));
  if (kTrueValues->find(base::ToLowerASCII(s)) != kTrueValues->end()) {
    *flag_ = true;
    return true;
  }
  if (kFalseValues->find(base::ToLowerASCII(s)) != kFalseValues->end()) {
    *flag_ = false;
    return true;
  }
  return false;
}

template <>
bool TypedQuicFlagHelper<int32_t>::SetFlag(const std::string& s) const {
  int32_t value;
  if (!base::StringToInt(s, &value)) {
    return false;
  }
  *flag_ = value;
  return true;
}

template <>
bool TypedQuicFlagHelper<QuicString>::SetFlag(const std::string& s) const {
  *flag_ = s;
  return true;
}

template class EXPORT_TEMPLATE_DEFINE(QUIC_EXPORT_PRIVATE)
    TypedQuicFlagHelper<bool>;
template class EXPORT_TEMPLATE_DEFINE(QUIC_EXPORT_PRIVATE)
    TypedQuicFlagHelper<int32_t>;
template class EXPORT_TEMPLATE_DEFINE(QUIC_EXPORT_PRIVATE)
    TypedQuicFlagHelper<QuicString>;

std::vector<QuicString> QuicParseCommandLineFlagsImpl(const char* usage,
                                                      int argc,
                                                      const char* const* argv) {
  base::CommandLine::Init(argc, argv);
  auto result = QuicParseCommandLineFlagsHelper(
      usage, *base::CommandLine::ForCurrentProcess());
  if (result.exit_status.has_value()) {
#if defined(STARBOARD)
    SbSystemBreakIntoDebugger();
#else
    exit(*result.exit_status);
#endif
  }
  return result.non_flag_args;
}

QuicParseCommandLineFlagsResult QuicParseCommandLineFlagsHelper(
    const char* usage,
    const base::CommandLine& command_line) {
  QuicParseCommandLineFlagsResult result;
  result.non_flag_args = ToQuicStringVector(command_line.GetArgs());
  if (command_line.HasSwitch("h") || command_line.HasSwitch("help")) {
    QuicPrintCommandLineFlagHelpImpl(usage);
    result.exit_status = 0;
  } else {
    std::string msg;
    if (!QuicFlagRegistry::GetInstance().SetFlags(command_line, &msg)) {
#if defined(STARBOARD)
      DLOG(ERROR) << msg;
#else
      std::cerr << msg << std::endl;
#endif
      result.exit_status = 1;
    }
  }
  return result;
}

void QuicPrintCommandLineFlagHelpImpl(const char* usage) {
#if defined(STARBOARD)
  DLOG(INFO) << usage << '\n'
#else
  std::cout << usage << std::endl
#endif
            << "Options:" << std::endl
            << QuicFlagRegistry::GetInstance().GetHelp() << std::endl;
}

}  // namespace quic
