// Copyright 2019 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/fidlcat/command_line_options.h"

#include <lib/cmdline/args_parser.h>
#include <lib/syslog/cpp/log_settings.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <filesystem>
#include <fstream>
#include <set>
#include <string>
#include <vector>

#include <re2/re2.h>

#include "src/lib/fxl/strings/string_number_conversions.h"
#include "tools/fidlcat/lib/decode_options.h"

namespace fidlcat {

int constexpr kMinColumns = 80;

const char* const kHelpIntro = R"(fidlcat [ <options> ] [ command [args] ]

  fidlcat will run the specified command until it exits.  It will intercept and
  record all fidl calls invoked by the process.  The command may be of the form
  "run <component URL>", in which case the given component will be launched.

  fidlcat will return the code 1 if its parameters are invalid.

  fidlcat expects a debug agent to be running on the target device.  It will
  return the code 2 if it cannot connect to the debug agent.

Options:

)";

const char* const kRemoteHostHelp = R"(  --connect
      The host and port of the debug agent running on the target Fuchsia
      instance, of the form [<ipv6_addr>]:port.)";

const char* const kUnixConnectHelp = R"(  --unix-connect=<filepath>
      Attempts to connect to a debug_agent through a unix socket.)";

const char* const kSymbolIndexHelp = R"(  --symbol-index=<path>
      Populates --ids-txt and --build-id-dir using the given symbol-index file,
      which defaults to ~/.fuchsia/debug/symbol-index. The file should be
      created and maintained by the "symbol-index" host tool.)";

const char* const kBuildIdDirHelp = R"(  --build-id-dir=<path>
      Adds the given directory to the symbol search path. Multiple
      --build-id-dir switches can be passed to add multiple directories.
      The directory must have the same structure as a .build-id directory,
      that is, each symbol file lives at xx/yyyyyyyy.debug where xx is
      the first two characters of the build ID and yyyyyyyy is the rest.
      However, the name of the directory doesn't need to be .build-id.)";

const char* const kSymbolServerHelp = R"(  --symbol-server=<url>
      Adds the given URL to symbol servers. Symbol servers host the debug
      symbols for prebuilt binaries and dynamic libraries.)";

const char* const kSymbolPathHelp = R"(  --symbol-path=<path>
  -s <path>
      Adds the given directory or file to the symbol search path. Multiple
      -s switches can be passed to add multiple locations. When a directory
      path is passed, the directory will be enumerated non-recursively to
      index all ELF files. When a file is passed, it will be loaded as an ELF
      file (if possible).)";

const char* const kSymbolCacheHelp = R"(  --symbol-cache=<path>
      Directory where we can keep a symbol cache. If a symbol server has been
      specified, downloaded symbols will be stored in this directory. The
      directory structure will be the same as a .build-id directory, and
      symbols will be read from this location as though you had specified
      "--build-id-dir=<path>".)";

const char* const kFidlIrPathHelp = R"(  --fidl-ir-path=<path>|@argfile
      Adds the given path as a repository for FIDL IR, in the form of .fidl.json
      files.  Passing a file adds the given file.  Passing a directory adds all
      of the .fidl.json files in that directory and any directory transitively
      reachable from there. An argfile contains a newline-separated list of
      .fidl.json files relative to the directory containing the argfile; passing
      an argfile (starting with the '@' character) adds all files listed in that
      argfile.  This switch can be passed multiple times to add multiple
      locations.)";

const char* const kIdsTxtHelp = R"(  --ids-txt=<path>
      Adds the given file to the symbol search path. Multiple --ids-txt
      switches can be passed to add multiple files. The file, typically named
      "ids.txt", serves as a mapping from build ID to symbol file path and
      should contain multiple lines in the format of "<build ID> <file path>".)";

const char* const kQuitAgentOnExitHelp = R"(  --quit-agent-on-exit
      Will send a quit message to a connected debug agent in order for it to
      shutdown. This is so that fidlcat doesn't leak unwanted debug agents on
      "on-the-fly" debugging sessions.)";

const char* const kFromHelp = R"(  --from=<source>
      This option must be used at most once.
      Source can be:
      --from=device This is the default input. The input comes from the live monitoring of one or
                    several processes.
                    At least one of '--remote-pid', '--remote-name', '--remote-job-id',
                    '--remote-job-name, 'run' must be specified.
      --from=dump   The input comes from stdin which is the log output of one or several programs.
                    The lines in the log which dump syscalls are decoded and replaced by the
                    decoded version.
                    All other lines are unchanged.
      --from=<path> The input comes from a previously recorded session (protobuf format). Path gives
                    the name of the file to read. If path is '-' then the standard input is used.)";

const char* const kToHelp = R"(  --to=<path>
      Save the session using protobuf in the specified file. All events are
      saved including the messages which have been filtered out by --messages
      or --exclude-messages.)";

const char* const kFormatHelp = R"(  --format=<output>
      This option must be used at most once.
      The output format can be:
      --format=pretty    The session is pretty printed (with colors).
                         This is the default output is --with is not used.
      --format=json      The session is printed using a json format.
      --format=textproto The session is printed using a text protobuf format.
      --format=none      Nothing is displayed on the standard output (this option only makes sense
                         when used with --to=<path> or with --with).
                         When there is no output, fidlcat is much faster (this is better when you
                         want to monitor real time components).
                         This is the default output is --with is used.)";

const char* const kWithHelp = R"(These options can be used several times.
  --with=summary
      At the end of the session, a summary of the session is displayed on the standard output.
  --with=summary=<path>
      Like --with=summary but the result is stored into the file specified by <path>.
  --with=top
      At the end of the session, generate a view that groups the output by process, protocol, and
      method. The groups are sorted by number of events, so groups with more associated events are
      listed earlier.
  --with=top=<path>
      Like --with=top but the result is stored into the file specified by <path>.
  --with=group-by-thread
      Like For each thread, display a short version of all the events.
  --with=group-by-thread=<path>
      Like --with=group-by-thread but the result is stored into the file specified by <path>.)";

const char* const kCompareHelp = R"(  --compare=<path>
      Compare output with the one stored in the given file)";

const char* const kWithProcessInfoHelp = R"(  --with-process-info
      Display the process name, process id and thread id on each line.)";

const char* const kStayAlive = R"(  --stay-alive
      Don't quit fidlcat when all the monitored processes have ended. This allows to keep monitoring
      upcoming process. At the end you have to use control-c to quit fidlcat. This is useful when
      you monitor a process and restart this process.)";

const char* const kStackHelp = R"(  --stack=<value>
      The amount of stack frame to display:
      - 0: no stack (default value)
      - 1: call site (1 to 4 levels)
      - 2: full stack frame (adds some overhead))";

const char* const kSyscallFilterHelp = R"(  --syscalls
      A regular expression which selects the syscalls to decode and display.
      Can be passed multiple times.
      By default, only zx_channel_.* syscalls are displayed.
      To display all the syscalls, use: --syscalls=".*")";

const char* const kExcludeSyscallFilterHelp = R"(  --exclude-syscalls
      A regular expression which selects the syscalls to not decode and display.
      Can be passed multiple times.
      To be displayed, a syscall must verify --syscalls and not verify
      --exclude-syscalls.
      To display all the syscalls but the zx_handle syscalls, use:
        --syscalls=".*" --exclude-syscalls="zx_handle_.*")";

const char* const kMessageFilterHelp = R"(  --messages
      A regular expression which selects the messages to display.
      To display a message, the method name must satisfy the regexp.
      This option can be specified multiple times.
      Message filtering works on the method's fully qualified name.)";

const char* const kExcludeMessageFilterHelp = R"(  --exclude-messages
      A regular expression which selects the messages to not display.
      If a message method name satisfy the regexp, the message is not displayed
      (even if it satifies --messages).
      This option can be specified multiple times.
      Message filtering works on the method's fully qualified name.)";

const char* const kTriggerFilterHelp = R"(  --trigger
      Start displaying messages and syscalls only when a message for which the
      method name satisfies the filter is found.
      This option can be specified multiple times.
      Message filtering works on the method's fully qualified name.)";

const char* const kThreadFilterHelp = R"(  --thread
      Only display the events for the specified thread.
      This option can be specified multiple times to display several threads.
      By default all the events are displayed.)";

const char* const kDumpMessagesHelp = R"(  --dump-messages
      Always display the message binary dump even if we can decode the message.
      By default the dump is only displayed if we can't decode the message.)";

const char* const kColorsHelp = R"(  --colors=[never|auto|always]
      For pretty print, use colors:
      - never
      - auto: only if running in a terminal (default value)
      - always)";

const char* const kColumnsHelp = R"(  --columns=<size>
      For pretty print, width of the display. By default, on a terminal, use
      the terminal width.)";

const char* const kVerbosityHelp = R"(  --verbose=<number or log level>
      The log verbosity.  Legal values are "info", "warning", "error", "fatal",
      or a number, starting from 0. Extra verbosity comes with higher levels)";

const char* const kQuietHelp = R"(  --quiet=<number or log level>
      The log verbosity.  Legal values are "info", "warning", "error", "fatal",
      or a number, starting from 0. Extra verbosity comes with lower levels.)";

const char* const kLogFileHelp = R"(  --log-file=<pathspec>
      The name of a file to which the log should be written.)";

const char* const kRemotePidHelp = R"(  --remote-pid
      The koid of the remote process. Can be passed multiple times.)";

const char* const kRemoteNameHelp = R"(  --remote-name=<name>
  -f <name>
      The name of a process. Fidlcat will monitor all existing and future
      processes whose names includes <name> (<name> is a substring of the
      process name).
      Can be provided multiple times for multiple names.
      When used with --remote-job-id or --remote-job-name, only the processes
      from the selected jobs are taken into account.
      For example:
          --remote-name echo_client.*.cmx
          --remote-name echo_client)";

const char* const kExtraNameHelp = R"(  --extra-name=<regexp>
      Like --remote-name, it monitors some processes. However, for these
      processes, monitoring starts only when one of of the "--remote-name"
      process is launched. Also, fidlcat stops when the last "--remote-name"
      process stops (even if some "--extra-name" processes are still
      monitored). You must specify at least one filter with --remote-name if
      you use this option (without --remote-name, nothing would be displayed).)";

const char* const kRemoteJobIdHelp = R"(  --remote-job-id
      The koid of a remote job for which we want to monitor all the processes.
      Can be provided multiple times for multiple jobs.
      Only jobs created before fidlcat is launched are monitored.)";

const char* const kRemoteJobNameHelp = R"(  The name of a remote job for which
      we want to monitor all the processes. All the jobs which contain <name> in
      their name are used.
      Can be provided multiple times for multiple jobs.
      Only jobs created before fidlcat is launched are monitored.)";

const char* const kHelpHelp = R"(  --help
  -h
      Prints all command-line switches.)";

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

const char* const kVersionHelp = R"(  --version
      Prints the version.)";

// Sets the process log settings.  The |level| is the value of the setting (as
// passed to --quiet or --verbose), |multiplier| is a value by which a numerical
// setting will be multiplied (basically, -1 for verbose and 1 for quiet), and
// |settings| contains the output.
bool SetLogSettings(const std::string& level, int multiplier, syslog::LogSettings* settings) {
  if (level == "trace") {
    settings->min_log_level = syslog::LOG_TRACE;
  } else if (level == "debug") {
    settings->min_log_level = syslog::LOG_DEBUG;
  } else if (level == "info") {
    settings->min_log_level = syslog::LOG_INFO;
  } else if (level == "warning") {
    settings->min_log_level = syslog::LOG_WARNING;
  } else if (level == "error") {
    settings->min_log_level = syslog::LOG_ERROR;
  } else if (level == "fatal") {
    settings->min_log_level = syslog::LOG_FATAL;
  } else if (fxl::StringToNumberWithError(level, &settings->min_log_level)) {
    settings->min_log_level =
        syslog::LOG_INFO + static_cast<syslog::LogSeverity>(
                               (multiplier * (multiplier > 0 ? syslog::LogSeverityStepSize
                                                             : syslog::LogVerbosityStepSize)));

  } else {
    return false;
  }
  return true;
}

cmdline::Status ProcessLogOptions(const CommandLineOptions* options) {
  syslog::LogSettings settings;
  if (options->verbose) {
    if (!SetLogSettings(*options->verbose, -1, &settings)) {
      return cmdline::Status::Error("Unable to parse verbose setting \"" + *options->verbose +
                                    "\"");
    }
  }
  if (options->quiet) {
    if (!SetLogSettings(*options->quiet, 1, &settings)) {
      return cmdline::Status::Error("Unable to parse quiet setting \"" + *options->quiet + "\"");
    }
  }
  if (options->log_file) {
    settings.log_file = *options->log_file;
  }
  syslog::SetLogSettings(settings);
  return cmdline::Status::Ok();
}

std::string ParseCommandLine(int argc, const char* argv[], CommandLineOptions* options,
                             DecodeOptions* decode_options, DisplayOptions* display_options,
                             std::vector<std::string>* params) {
  using analytics::core_dev_tools::AnalyticsOption;
  using analytics::core_dev_tools::ParseAnalyticsOption;

  cmdline::ArgsParser<CommandLineOptions> parser;

  // Debug agent options:
  parser.AddSwitch("connect", 'r', kRemoteHostHelp, &CommandLineOptions::connect);
  parser.AddSwitch("unix-connect", 0, kUnixConnectHelp, &CommandLineOptions::unix_connect);
  parser.AddSwitch("symbol-index", 0, kSymbolIndexHelp, &CommandLineOptions::symbol_index_files);
  parser.AddSwitch("build-id-dir", 0, kBuildIdDirHelp, &CommandLineOptions::build_id_dirs);
  parser.AddSwitch("symbol-server", 0, kSymbolServerHelp, &CommandLineOptions::symbol_servers);
  parser.AddSwitch("symbol-path", 's', kSymbolPathHelp, &CommandLineOptions::symbol_paths);
  parser.AddSwitch("symbol-cache", 0, kSymbolCacheHelp, &CommandLineOptions::symbol_cache);
  // Fidlcat system options:
  parser.AddSwitch("fidl-ir-path", 0, kFidlIrPathHelp, &CommandLineOptions::fidl_ir_paths);
  parser.AddSwitch("ids-txt", 0, kIdsTxtHelp, &CommandLineOptions::ids_txts);
  parser.AddSwitch("quit-agent-on-exit", 0, kQuitAgentOnExitHelp,
                   &CommandLineOptions::quit_agent_on_exit);
  // Input option:
  parser.AddSwitch("from", 0, kFromHelp, &CommandLineOptions::from);
  // Session save option:
  parser.AddSwitch("to", 0, kToHelp, &CommandLineOptions::to);
  // Format (output) option:
  parser.AddSwitch("format", 0, kFormatHelp, &CommandLineOptions::format);
  // Extra generation:
  parser.AddSwitch("with", 0, kWithHelp, &CommandLineOptions::extra_generation);
  // Session comparison option:
  parser.AddSwitch("compare", 'c', kCompareHelp, &CommandLineOptions::compare_file);
  // Display options:
  parser.AddSwitch("with-process-info", 0, kWithProcessInfoHelp,
                   &CommandLineOptions::with_process_info);
  parser.AddSwitch("stay-alive", 0, kStayAlive, &CommandLineOptions::stay_alive);
  parser.AddSwitch("stack", 0, kStackHelp, &CommandLineOptions::stack_level);
  parser.AddSwitch("syscalls", 0, kSyscallFilterHelp, &CommandLineOptions::syscall_filters);
  parser.AddSwitch("exclude-syscalls", 0, kExcludeSyscallFilterHelp,
                   &CommandLineOptions::exclude_syscall_filters);
  parser.AddSwitch("messages", 0, kMessageFilterHelp, &CommandLineOptions::message_filters);
  parser.AddSwitch("exclude-messages", 0, kExcludeMessageFilterHelp,
                   &CommandLineOptions::exclude_message_filters);
  parser.AddSwitch("trigger", 0, kTriggerFilterHelp, &CommandLineOptions::trigger_filters);
  parser.AddSwitch("thread", 0, kThreadFilterHelp, &CommandLineOptions::thread_filters);
  parser.AddSwitch("dump-messages", 0, kDumpMessagesHelp, &CommandLineOptions::dump_messages);
  parser.AddSwitch("colors", 0, kColorsHelp, &CommandLineOptions::colors);
  parser.AddSwitch("columns", 0, kColumnsHelp, &CommandLineOptions::columns);
  // Logging options:
  parser.AddSwitch("verbose", 'v', kVerbosityHelp, &CommandLineOptions::verbose);
  parser.AddSwitch("quiet", 'q', kQuietHelp, &CommandLineOptions::quiet);
  parser.AddSwitch("log-file", 0, kLogFileHelp, &CommandLineOptions::log_file);
  // Monitoring options:
  parser.AddSwitch("remote-pid", 'p', kRemotePidHelp, &CommandLineOptions::remote_pid);
  parser.AddSwitch("remote-name", 'f', kRemoteNameHelp, &CommandLineOptions::remote_name);
  parser.AddSwitch("extra-name", 0, kExtraNameHelp, &CommandLineOptions::extra_name);
  parser.AddSwitch("remote-job-id", 0, kRemoteJobIdHelp, &CommandLineOptions::remote_job_id);
  parser.AddSwitch("remote-job-name", 0, kRemoteJobNameHelp, &CommandLineOptions::remote_job_name);

  parser.AddSwitch("version", 0, kVersionHelp, &CommandLineOptions::requested_version);

  parser.AddSwitch("analytics", 0, kAnalyticsHelp, &CommandLineOptions::analytics);
  parser.AddSwitch("analytics-show", 0, kAnalyticsShowHelp, &CommandLineOptions::analytics_show);

  bool requested_help = false;
  parser.AddGeneralSwitch("help", 'h', kHelpHelp, [&requested_help]() { requested_help = true; });

  cmdline::Status status = parser.Parse(argc, argv, options, params);
  if (status.has_error()) {
    return status.error_message();
  }

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

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

  status = ProcessLogOptions(options);
  if (status.has_error()) {
    return status.error_message();
  }

  if (options->connect && options->unix_connect) {
    return "Only one of '--connect' and '--unix-connect' can be specified";
  }

  bool device = options->from.empty() || (options->from == "device");
  bool watch = !options->remote_name.empty() || !options->remote_pid.empty() ||
               !options->remote_job_name.empty() || !options->remote_job_id.empty() ||
               (std::find(params->begin(), params->end(), "run") != params->end());

  if (requested_help || (device && !watch) ||
      (!options->extra_name.empty() && options->remote_name.empty())) {
    return kHelpIntro + parser.GetHelp();
  }

  // Default values for symbol_cache and symbol_index_files.
  if (const char* home = std::getenv("HOME"); home) {
    std::string home_str = home;
    if (!options->symbol_cache) {
      options->symbol_cache = home_str + "/.fuchsia/debug/symbol-cache";
    }
    if (options->symbol_index_files.empty()) {
      for (const auto& path : {home_str + "/.fuchsia/debug/symbol-index.json",
                               home_str + "/.fuchsia/debug/symbol-index"}) {
        std::error_code ec;
        if (std::filesystem::exists(path, ec)) {
          options->symbol_index_files.push_back(path);
        }
      }
    }
  }

  decode_options->stay_alive = options->stay_alive;
  decode_options->stack_level = options->stack_level;
  if (options->syscall_filters.empty()) {
    decode_options->syscall_filters.emplace_back(std::make_unique<re2::RE2>("zx_channel_.*"));
    decode_options->syscall_filters.emplace_back(std::make_unique<re2::RE2>("zx_handle_close"));
    decode_options->syscall_filters.emplace_back(
        std::make_unique<re2::RE2>("zx_handle_close_many"));
  } else if ((options->syscall_filters.size() != 1) || (options->syscall_filters[0] != ".*")) {
    for (const auto& filter : options->syscall_filters) {
      auto r = std::make_unique<re2::RE2>(filter);
      if (!r->ok()) {
        return "Bad filter for --syscalls: " + filter;
      }
      decode_options->syscall_filters.push_back(std::move(r));
    }
  }
  for (const auto& filter : options->exclude_syscall_filters) {
    auto r = std::make_unique<re2::RE2>(filter);
    if (!r->ok()) {
      return "Bad filter for --exclude-syscalls: " + filter;
    }
    decode_options->exclude_syscall_filters.push_back(std::move(r));
  }
  for (const auto& filter : options->message_filters) {
    auto r = std::make_unique<re2::RE2>(filter);
    if (!r->ok()) {
      return "Bad filter for --messages: " + filter;
    }
    decode_options->message_filters.push_back(std::move(r));
  }
  for (const auto& filter : options->exclude_message_filters) {
    auto r = std::make_unique<re2::RE2>(filter);
    if (!r->ok()) {
      return "Bad filter for --exclude-messages: " + filter;
    }
    decode_options->exclude_message_filters.push_back(std::move(r));
  }
  for (const auto& filter : options->trigger_filters) {
    auto r = std::make_unique<re2::RE2>(filter);
    if (!r->ok()) {
      return "Bad filter for --trigger: " + filter;
    }
    decode_options->trigger_filters.push_back(std::move(r));
  }
  for (const auto& filter : options->thread_filters) {
    decode_options->thread_filters.emplace_back(static_cast<zx_koid_t>(std::stol(filter)));
  }

  decode_options->save = options->to;

  display_options->with_process_info = options->with_process_info;

  struct winsize term_size;
  term_size.ws_col = 0;
  int ioctl_result = ioctl(STDOUT_FILENO, TIOCGWINSZ, &term_size);
  if (options->columns == 0) {
    display_options->columns = term_size.ws_col;
    display_options->columns = std::max(display_options->columns, kMinColumns);
  } else {
    display_options->columns = options->columns;
  }

  display_options->dump_messages = options->dump_messages;

  if (!options->from.empty() && (options->from == "dump")) {
    decode_options->input_mode = InputMode::kDump;
  } else if (!options->from.empty() && (options->from != "device")) {
    decode_options->input_mode = InputMode::kFile;
  } else {
    if (options->connect && options->unix_connect) {
      return "'--connect' or '--unix-connect' options expected";
    }
  }

  if ((!options->format.has_value() && options->extra_generation.empty()) ||
      (options->format.has_value() && (options->format.value() == "pretty"))) {
    decode_options->output_mode = OutputMode::kStandard;
    display_options->pretty_print = true;
    display_options->needs_colors =
        ((options->colors == "always") || ((options->colors == "auto") && (ioctl_result != -1))) &&
        !(options->compare_file.has_value());
  } else if (options->format.has_value()) {
    if (options->format.value() == "json") {
      decode_options->output_mode = OutputMode::kStandard;
    } else if (options->format.value() == "textproto") {
      decode_options->output_mode = OutputMode::kTextProtobuf;
    } else if (options->format.value() == "none") {
    } else {
      return "Invalid format " + options->format.value() + " for option --format.";
    }
  }

  display_options->extra_generation_needs_colors =
      ((options->colors == "always") || ((options->colors == "auto") && (ioctl_result != -1)));

  for (const auto& extra_generation : options->extra_generation) {
    if (extra_generation == "summary") {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kSummary, "");
    } else if (extra_generation.find("summary=") == 0) {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kSummary,
                                          extra_generation.substr(8));
    } else if (extra_generation == "top") {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kTop, "");
    } else if (extra_generation.find("top=") == 0) {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kTop, extra_generation.substr(4));
    } else if (extra_generation == "generate-tests") {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kCpp, "");
    } else if (extra_generation.find("generate-tests=") == 0) {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kCpp, extra_generation.substr(15));
    } else if (extra_generation == "group-by-thread") {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kThreads, "");
    } else if (extra_generation.find("group-by-thread=") == 0) {
      display_options->AddExtraGeneration(ExtraGeneration::Kind::kThreads,
                                          extra_generation.substr(16));
    } else {
      return "Invalid generation " + extra_generation + " for option --with.";
    }
  }

  return "";
}

namespace {

bool EndsWith(const std::string& value, const std::string& suffix) {
  if (suffix.size() > value.size()) {
    return false;
  }
  return std::equal(suffix.rbegin(), suffix.rend(), value.rbegin());
}

}  // namespace

void ExpandFidlPathsFromOptions(std::vector<std::string> cli_ir_paths,
                                std::vector<std::string>& paths,
                                std::vector<std::string>& bad_paths) {
  // Strip out argfiles before doing path processing.
  for (int64_t i = cli_ir_paths.size() - 1; i >= 0; i--) {
    std::string& path = cli_ir_paths[i];
    if (path.compare(0, 1, "@") == 0) {
      std::filesystem::path real_path(path.substr(1));
      auto enclosing_directory = real_path.parent_path();
      std::string file = path.substr(1);
      cli_ir_paths.erase(cli_ir_paths.begin() + i);

      std::ifstream infile(file, std::ifstream::in);
      if (!infile.good()) {
        bad_paths.push_back(file);
        continue;
      }

      std::string jsonfile_path;
      while (infile >> jsonfile_path) {
        if (std::filesystem::path(jsonfile_path).is_relative()) {
          jsonfile_path = enclosing_directory.string() +
                          std::filesystem::path::preferred_separator + jsonfile_path;
        }

        paths.push_back(jsonfile_path);
      }
    }
  }

  std::set<std::string> checked_dirs;
  // Repeat until cli_ir_paths is empty:
  //  If it is a directory, add the directory contents to the cli_ir_paths.
  //  If it is a .fidl.json file, add it to |paths|.
  while (!cli_ir_paths.empty()) {
    std::string current_string = cli_ir_paths.back();
    cli_ir_paths.pop_back();
    std::filesystem::path current_path = current_string;
    if (std::filesystem::is_directory(current_path)) {
      for (auto& dir_ent : std::filesystem::directory_iterator(current_path)) {
        std::string ent_name = dir_ent.path().string();
        if (std::filesystem::is_directory(ent_name)) {
          auto found = checked_dirs.find(ent_name);
          if (found == checked_dirs.end()) {
            checked_dirs.insert(ent_name);
            cli_ir_paths.push_back(ent_name);
          }
        } else if (EndsWith(ent_name, ".fidl.json")) {
          paths.push_back(dir_ent.path());
        }
      }
    } else if (std::filesystem::is_regular_file(current_path) &&
               EndsWith(current_string, ".fidl.json")) {
      paths.push_back(current_string);
    } else {
      bad_paths.push_back(current_string);
    }
  }
}

}  // namespace fidlcat
