// Copyright 2016 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 "src/lib/fxl/command_line.h"

namespace fxl {

// CommandLine -----------------------------------------------------------------

CommandLine::Option::Option(const std::string& name) : name(name) {}

CommandLine::Option::Option(const std::string& name, const std::string& value)
    : name(name), value(value) {}

CommandLine::CommandLine() = default;

CommandLine::CommandLine(const CommandLine& from) = default;

CommandLine::CommandLine(CommandLine&& from) = default;

CommandLine::CommandLine(const std::string& argv0, const std::vector<Option>& options,
                         const std::vector<std::string>& positional_args)
    : has_argv0_(true), argv0_(argv0), options_(options), positional_args_(positional_args) {
  for (size_t i = 0; i < options_.size(); i++)
    option_index_[options_[i].name] = i;
}

CommandLine::~CommandLine() = default;

CommandLine& CommandLine::operator=(const CommandLine& from) = default;

CommandLine& CommandLine::operator=(CommandLine&& from) = default;

bool CommandLine::HasOption(std::string_view name, size_t* index) const {
  auto it = option_index_.find(std::string(name));
  if (it == option_index_.end())
    return false;
  if (index)
    *index = it->second;
  return true;
}

bool CommandLine::GetOptionValue(std::string_view name, std::string* value) const {
  size_t index;
  if (!HasOption(name, &index))
    return false;
  *value = options_[index].value;
  return true;
}

std::vector<std::string_view> CommandLine::GetOptionValues(std::string_view name) const {
  std::vector<std::string_view> ret;
  for (const auto& option : options_) {
    if (option.name == name)
      ret.push_back(option.value);
  }
  return ret;
}

std::string CommandLine::GetOptionValueWithDefault(std::string_view name,
                                                   std::string_view default_value) const {
  size_t index;
  if (!HasOption(name, &index))
    return std::string(default_value);
  return options_[index].value;
}

// Factory functions (etc.) ----------------------------------------------------

namespace internal {

CommandLineBuilder::CommandLineBuilder() {}
CommandLineBuilder::~CommandLineBuilder() {}

bool CommandLineBuilder::ProcessArg(const std::string& arg) {
  if (!has_argv0_) {
    has_argv0_ = true;
    argv0_ = arg;
    return false;
  }

  // If we've seen a positional argument, then the remaining arguments are also
  // positional.
  if (started_positional_args_) {
    bool rv = positional_args_.empty();
    positional_args_.push_back(arg);
    return rv;
  }

  // Anything that doesn't start with "--" is a positional argument.
  if (arg.size() < 2u || arg[0] != '-' || arg[1] != '-') {
    bool rv = positional_args_.empty();
    started_positional_args_ = true;
    positional_args_.push_back(arg);
    return rv;
  }

  // "--" ends option processing, but isn't stored as a positional argument.
  if (arg.size() == 2u) {
    started_positional_args_ = true;
    return false;
  }

  // Note: The option name *must* be at least one character, so start at
  // position 3 -- "--=foo" will yield a name of "=foo" and no value. (Passing a
  // starting |pos| that's "too big" is OK.)
  size_t equals_pos = arg.find('=', 3u);
  if (equals_pos == std::string::npos) {
    options_.push_back(CommandLine::Option(arg.substr(2u)));
    return false;
  }

  options_.push_back(
      CommandLine::Option(arg.substr(2u, equals_pos - 2u), arg.substr(equals_pos + 1u)));
  return false;
}

CommandLine CommandLineBuilder::Build() const {
  if (!has_argv0_)
    return CommandLine();
  return CommandLine(argv0_, options_, positional_args_);
}

}  // namespace internal

std::vector<std::string> CommandLineToArgv(const CommandLine& command_line) {
  if (!command_line.has_argv0())
    return std::vector<std::string>();

  std::vector<std::string> argv;
  const std::vector<CommandLine::Option>& options = command_line.options();
  const std::vector<std::string>& positional_args = command_line.positional_args();
  // Reserve space for argv[0], options, maybe a "--" (if needed), and the
  // positional arguments.
  argv.reserve(1u + options.size() + 1u + positional_args.size());

  argv.push_back(command_line.argv0());
  for (const auto& option : options) {
    if (option.value.empty())
      argv.push_back("--" + option.name);
    else
      argv.push_back("--" + option.name + "=" + option.value);
  }

  if (!positional_args.empty()) {
    // Insert a "--" if necessary.
    if (positional_args[0].size() >= 2u && positional_args[0][0] == '-' &&
        positional_args[0][1] == '-')
      argv.push_back("--");

    argv.insert(argv.end(), positional_args.begin(), positional_args.end());
  }

  return argv;
}

}  // namespace fxl
