// Copyright 2020 The Fuchsia 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 "tools/symbol-index/command_line_options.h"

#include <lib/cmdline/args_parser.h>

#include "src/lib/fxl/strings/string_printf.h"

namespace symbol_index {

namespace {

const char kHelpIntro[] = R"(symbol-index [ <options> ] <verb> [ <arguments> ... ]

  Manipulates a symbol-index file.

Available verbs:

  list
      Lists all paths in symbol-index.

  add <symbol path> [ <build directory> ]
      Adds a new symbol path to symbol-index. A symbol path could be either a
      a text file in "ids.txt" format, or a directory in ".build-id" structure.
      An optional build directory could be supplemented, which is used by zxdb
      to locate the source code. If the symbol path is already in symbol-index,
      no changes will be made regardless of the optional build directory.

  add-all [ <input file> ]
      Reads the input and adds all symbol paths with optional build directories.
      The input file can contain multiple lines, each describing a symbol path.
      An optional build directory could be supplemented and separated from the
      symbol path with whitespaces. Relative paths will be resolved based on
      the input file. Empty lines and lines starting with "#" will be ignored.
      If the input file is not specified, the input will be read from the stdin.

  remove <symbol path>
      Removes a symbol path from symbol-index.

  purge
      Removes all non-existent paths from symbol-index.

Options

)";

const char kConfigHelp[] = R"(  --config=<path>
  -c <path>
      Path to the symbol-index config file, default to
      ~/.fuchsia/debug/symbol-index.)";

const char kHelpHelp[] = R"(  --help
  -h
      Prints this help.)";

const char kVersionHelp[] = R"(  --version
  -v
      Prints the version.)";

using ::analytics::core_dev_tools::kAnalyticsHelp;
using ::analytics::core_dev_tools::kAnalyticsShowHelp;

}  // namespace

Error CommandLineOptions::SetVerb(const std::string& str) {
  if (str == "list")
    verb = Verb::kList;
  else if (str == "add")
    verb = Verb::kAdd;
  else if (str == "add-all")
    verb = Verb::kAddAll;
  else if (str == "remove")
    verb = Verb::kRemove;
  else if (str == "purge")
    verb = Verb::kPurge;
  else
    return fxl::StringPrintf("Unsupported verb: %s", str.c_str());
  return "";
}

Error CommandLineOptions::Validate() {
  size_t params_size = params.size();
  switch (verb) {
    case Verb::kList:
      if (params_size != 0)
        return fxl::StringPrintf("Verb list requires 0 arguments, but %lu is given.", params_size);
      break;
    case Verb::kAdd:
      if (params_size < 1 || params_size > 2) {
        return fxl::StringPrintf("Verb add requires 1 or 2 arguments, but %lu is given.",
                                 params_size);
      }
      break;
    case Verb::kAddAll:
      if (params_size > 1) {
        return fxl::StringPrintf("Verb add-all requires 0 or 1 arguments, but %lu is given.",
                                 params_size);
      }
      break;
    case Verb::kRemove:
      if (params_size != 1)
        return fxl::StringPrintf("Verb remove requires 1 argument, but %lu is given.", params_size);
      break;
    case Verb::kPurge:
      if (params_size != 0)
        return fxl::StringPrintf("Verb purge requires 0 arguments, but %lu is given.", params_size);
      break;
  }
  return "";
}

Error ParseCommandLine(int argc, const char* argv[], CommandLineOptions* options) {
  using analytics::core_dev_tools::AnalyticsOption;
  using analytics::core_dev_tools::ParseAnalyticsOption;

  std::vector<std::string> params;
  cmdline::ArgsParser<CommandLineOptions> parser;

  parser.AddSwitch("config", 'c', kConfigHelp, &CommandLineOptions::symbol_index_file);
  parser.AddSwitch("version", 'v', kVersionHelp, &CommandLineOptions::requested_version);
  parser.AddSwitch("analytics", 0, kAnalyticsHelp, &CommandLineOptions::analytics);
  parser.AddSwitch("analytics-show", 0, kAnalyticsShowHelp, &CommandLineOptions::analytics_show);

  // Special --help switch which doesn't exist in the options structure.
  bool requested_help = false;
  parser.AddGeneralSwitch("help", 'h', kHelpHelp, [&requested_help]() { requested_help = true; });

  auto s = parser.Parse(argc, argv, options, &params);
  if (s.has_error()) {
    return s.error_message();
  }

  if (options->requested_version) {
    return "";
  }

  if (options->analytics_show || options->analytics == AnalyticsOption::kEnable ||
      options->analytics == AnalyticsOption::kDisable) {
    return "";
  }

  if (requested_help || params.empty()) {
    return kHelpIntro + parser.GetHelp();
  }

  if (Error err = options->SetVerb(params[0]); !err.empty()) {
    return err;
  }

  options->params.resize(params.size() - 1);
  std::copy(params.begin() + 1, params.end(), options->params.begin());

  if (Error err = options->Validate(); !err.empty()) {
    return err;
  }

  return "";
}

}  // namespace symbol_index
