// 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(StringView name, size_t* index) const {
  auto it = option_index_.find(name.ToString());
  if (it == option_index_.end())
    return false;
  if (index)
    *index = it->second;
  return true;
}

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

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

std::string CommandLine::GetOptionValueWithDefault(
    StringView name, StringView default_value) const {
  size_t index;
  if (!HasOption(name, &index))
    return default_value.ToString();
  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
