// Copyright (c) 2011 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 "base/command_line.h"

#include <algorithm>
#include <ostream>

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
#endif

CommandLine* CommandLine::current_process_commandline_ = NULL;

namespace {
typedef CommandLine::StringType::value_type CharType;

const CharType kSwitchTerminator[] = FILE_PATH_LITERAL("--");
const CharType kSwitchValueSeparator[] = FILE_PATH_LITERAL("=");
// Since we use a lazy match, make sure that longer versions (like "--") are
// listed before shorter versions (like "-") of similar prefixes.
#if defined(OS_WIN)
const CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"};
#elif defined(OS_POSIX)
// Unixes don't use slash as a switch.
const CharType* const kSwitchPrefixes[] = {"--", "-"};
#endif

#if defined(OS_WIN)
// Lowercase a string for case-insensitivity of switches.
// Is this desirable? It exists for backwards compatibility on Windows.
void Lowercase(std::string* arg) {
  transform(arg->begin(), arg->end(), arg->begin(), tolower);
}

// Quote a string if necessary, such that CommandLineToArgvW() will always
// process it as a single argument.
std::wstring WindowsStyleQuote(const std::wstring& arg) {
  // We follow the quoting rules of CommandLineToArgvW.
  // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
  if (arg.find_first_of(L" \\\"") == std::wstring::npos) {
    // No quoting necessary.
    return arg;
  }

  std::wstring out;
  out.push_back(L'"');
  for (size_t i = 0; i < arg.size(); ++i) {
    if (arg[i] == '\\') {
      // Find the extent of this run of backslashes.
      size_t start = i, end = start + 1;
      for (; end < arg.size() && arg[end] == '\\'; ++end)
        /* empty */;
      size_t backslash_count = end - start;

      // Backslashes are escapes only if the run is followed by a double quote.
      // Since we also will end the string with a double quote, we escape for
      // either a double quote or the end of the string.
      if (end == arg.size() || arg[end] == '"') {
        // To quote, we need to output 2x as many backslashes.
        backslash_count *= 2;
      }
      for (size_t j = 0; j < backslash_count; ++j)
        out.push_back('\\');

      // Advance i to one before the end to balance i++ in loop.
      i = end - 1;
    } else if (arg[i] == '"') {
      out.push_back('\\');
      out.push_back('"');
    } else {
      out.push_back(arg[i]);
    }
  }
  out.push_back('"');

  return out;
}
#endif

// Returns true and fills in |switch_string| and |switch_value| if
// |parameter_string| represents a switch.
bool IsSwitch(const CommandLine::StringType& parameter_string,
              std::string* switch_string,
              CommandLine::StringType* switch_value) {
  switch_string->clear();
  switch_value->clear();

  for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) {
    CommandLine::StringType prefix(kSwitchPrefixes[i]);
    if (parameter_string.find(prefix) != 0)
      continue;

    const size_t switch_start = prefix.length();
    const size_t equals_position = parameter_string.find(
        kSwitchValueSeparator, switch_start);
    CommandLine::StringType switch_native;
    if (equals_position == CommandLine::StringType::npos) {
      switch_native = parameter_string.substr(switch_start);
    } else {
      switch_native = parameter_string.substr(
          switch_start, equals_position - switch_start);
      *switch_value = parameter_string.substr(equals_position + 1);
    }
#if defined(OS_WIN)
    *switch_string = WideToASCII(switch_native);
    Lowercase(switch_string);
#else
    *switch_string = switch_native;
#endif

    return true;
  }

  return false;
}

}  // namespace

CommandLine::CommandLine(NoProgram no_program) {
#if defined(OS_POSIX)
  // Push an empty argument, because we always assume argv_[0] is a program.
  argv_.push_back("");
#endif
}

CommandLine::CommandLine(const FilePath& program) {
#if defined(OS_WIN)
  if (!program.empty()) {
    program_ = program.value();
    // TODO(evanm): proper quoting here.
    command_line_string_ = L'"' + program.value() + L'"';
  }
#elif defined(OS_POSIX)
  argv_.push_back(program.value());
#endif
}

#if defined(OS_POSIX)
CommandLine::CommandLine(int argc, const char* const* argv) {
  InitFromArgv(argc, argv);
}

CommandLine::CommandLine(const StringVector& argv) {
  InitFromArgv(argv);
}
#endif  // OS_POSIX

CommandLine::~CommandLine() {
}

// static
void CommandLine::Init(int argc, const char* const* argv) {
  delete current_process_commandline_;
  current_process_commandline_ = new CommandLine;
#if defined(OS_WIN)
  current_process_commandline_->ParseFromString(::GetCommandLineW());
#elif defined(OS_POSIX)
  current_process_commandline_->InitFromArgv(argc, argv);
#endif
}

// static
void CommandLine::Reset() {
  DCHECK(current_process_commandline_);
  delete current_process_commandline_;
  current_process_commandline_ = NULL;
}

// static
CommandLine* CommandLine::ForCurrentProcess() {
  DCHECK(current_process_commandline_);
  return current_process_commandline_;
}

#if defined(OS_WIN)
// static
CommandLine CommandLine::FromString(const std::wstring& command_line) {
  CommandLine cmd;
  cmd.ParseFromString(command_line);
  return cmd;
}
#endif  // OS_WIN

#if defined(OS_POSIX)
void CommandLine::InitFromArgv(int argc, const char* const* argv) {
  for (int i = 0; i < argc; ++i)
    argv_.push_back(argv[i]);
  InitFromArgv(argv_);
}

void CommandLine::InitFromArgv(const StringVector& argv) {
  argv_ = argv;
  bool parse_switches = true;
  for (size_t i = 1; i < argv_.size(); ++i) {
    const std::string& arg = argv_[i];

    if (!parse_switches) {
      args_.push_back(arg);
      continue;
    }

    if (arg == kSwitchTerminator) {
      parse_switches = false;
      continue;
    }

    std::string switch_string;
    StringType switch_value;
    if (IsSwitch(arg, &switch_string, &switch_value)) {
      switches_[switch_string] = switch_value;
    } else {
      args_.push_back(arg);
    }
  }
}
#endif  // OS_POSIX

CommandLine::StringType CommandLine::command_line_string() const {
#if defined(OS_WIN)
  return command_line_string_;
#elif defined(OS_POSIX)
  return JoinString(argv_, ' ');
#endif
}

FilePath CommandLine::GetProgram() const {
#if defined(OS_WIN)
  return FilePath(program_);
#else
  DCHECK_GT(argv_.size(), 0U);
  return FilePath(argv_[0]);
#endif
}

bool CommandLine::HasSwitch(const std::string& switch_string) const {
  std::string lowercased_switch(switch_string);
#if defined(OS_WIN)
  Lowercase(&lowercased_switch);
#endif
  return switches_.find(lowercased_switch) != switches_.end();
}

std::string CommandLine::GetSwitchValueASCII(
    const std::string& switch_string) const {
  CommandLine::StringType value = GetSwitchValueNative(switch_string);
  if (!IsStringASCII(value)) {
    LOG(WARNING) << "Value of --" << switch_string << " must be ASCII.";
    return "";
  }
#if defined(OS_WIN)
  return WideToASCII(value);
#else
  return value;
#endif
}

FilePath CommandLine::GetSwitchValuePath(
    const std::string& switch_string) const {
  return FilePath(GetSwitchValueNative(switch_string));
}

CommandLine::StringType CommandLine::GetSwitchValueNative(
    const std::string& switch_string) const {
  std::string lowercased_switch(switch_string);
#if defined(OS_WIN)
  Lowercase(&lowercased_switch);
#endif

  SwitchMap::const_iterator result = switches_.find(lowercased_switch);

  if (result == switches_.end()) {
    return CommandLine::StringType();
  } else {
    return result->second;
  }
}

size_t CommandLine::GetSwitchCount() const {
  return switches_.size();
}

void CommandLine::AppendSwitch(const std::string& switch_string) {
#if defined(OS_WIN)
  command_line_string_.append(L" ");
  command_line_string_.append(kSwitchPrefixes[0] + ASCIIToWide(switch_string));
  switches_[switch_string] = L"";
#elif defined(OS_POSIX)
  argv_.push_back(kSwitchPrefixes[0] + switch_string);
  switches_[switch_string] = "";
#endif
}

void CommandLine::AppendSwitchPath(const std::string& switch_string,
                                   const FilePath& path) {
  AppendSwitchNative(switch_string, path.value());
}

void CommandLine::AppendSwitchNative(const std::string& switch_string,
                                     const CommandLine::StringType& value) {
#if defined(OS_WIN)
  StringType combined_switch_string =
      kSwitchPrefixes[0] + ASCIIToWide(switch_string);
  if (!value.empty())
    combined_switch_string += kSwitchValueSeparator + WindowsStyleQuote(value);

  command_line_string_.append(L" ");
  command_line_string_.append(combined_switch_string);

  switches_[switch_string] = value;
#elif defined(OS_POSIX)
  StringType combined_switch_string = kSwitchPrefixes[0] + switch_string;
  if (!value.empty())
    combined_switch_string += kSwitchValueSeparator + value;
  argv_.push_back(combined_switch_string);
  switches_[switch_string] = value;
#endif
}

void CommandLine::AppendSwitchASCII(const std::string& switch_string,
                                    const std::string& value_string) {
#if defined(OS_WIN)
  AppendSwitchNative(switch_string, ASCIIToWide(value_string));
#elif defined(OS_POSIX)
  AppendSwitchNative(switch_string, value_string);
#endif
}

void CommandLine::AppendSwitches(const CommandLine& other) {
  SwitchMap::const_iterator i;
  for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
    AppendSwitchNative(i->first, i->second);
}

void CommandLine::CopySwitchesFrom(const CommandLine& source,
                                   const char* const switches[],
                                   size_t count) {
  for (size_t i = 0; i < count; ++i) {
    if (source.HasSwitch(switches[i])) {
      StringType value = source.GetSwitchValueNative(switches[i]);
      AppendSwitchNative(switches[i], value);
    }
  }
}

void CommandLine::AppendArg(const std::string& value) {
#if defined(OS_WIN)
  DCHECK(IsStringUTF8(value));
  AppendArgNative(UTF8ToWide(value));
#elif defined(OS_POSIX)
  AppendArgNative(value);
#endif
}

void CommandLine::AppendArgPath(const FilePath& path) {
  AppendArgNative(path.value());
}

void CommandLine::AppendArgNative(const CommandLine::StringType& value) {
#if defined(OS_WIN)
  command_line_string_.append(L" ");
  command_line_string_.append(WindowsStyleQuote(value));
  args_.push_back(value);
#elif defined(OS_POSIX)
  DCHECK(IsStringUTF8(value));
  argv_.push_back(value);
#endif
}

void CommandLine::AppendArgs(const CommandLine& other) {
  if(other.args_.size() <= 0)
    return;
#if defined(OS_WIN)
  command_line_string_.append(L" --");
#endif  // OS_WIN
  StringVector::const_iterator i;
  for (i = other.args_.begin(); i != other.args_.end(); ++i)
    AppendArgNative(*i);
}

void CommandLine::AppendArguments(const CommandLine& other,
                                  bool include_program) {
#if defined(OS_WIN)
  // Verify include_program is used correctly.
  DCHECK(!include_program || !other.GetProgram().empty());
  if (include_program)
    program_ = other.program_;

  if (!command_line_string_.empty())
    command_line_string_ += L' ';

  command_line_string_ += other.command_line_string_;
#elif defined(OS_POSIX)
  // Verify include_program is used correctly.
  // Logic could be shorter but this is clearer.
  DCHECK_EQ(include_program, !other.GetProgram().empty());

  if (include_program)
    argv_[0] = other.argv_[0];

  // Skip the first arg when copying since it's the program but push all
  // arguments to our arg vector.
  for (size_t i = 1; i < other.argv_.size(); ++i)
    argv_.push_back(other.argv_[i]);
#endif

  SwitchMap::const_iterator i;
  for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
    switches_[i->first] = i->second;
}

void CommandLine::PrependWrapper(const CommandLine::StringType& wrapper) {
  // The wrapper may have embedded arguments (like "gdb --args"). In this case,
  // we don't pretend to do anything fancy, we just split on spaces.
  if (wrapper.empty())
    return;
  StringVector wrapper_and_args;
#if defined(OS_WIN)
  base::SplitString(wrapper, ' ', &wrapper_and_args);
  program_ = wrapper_and_args[0];
  command_line_string_ = wrapper + L" " + command_line_string_;
#elif defined(OS_POSIX)
  base::SplitString(wrapper, ' ', &wrapper_and_args);
  argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end());
#endif
}

#if defined(OS_WIN)
void CommandLine::ParseFromString(const std::wstring& command_line) {
  TrimWhitespace(command_line, TRIM_ALL, &command_line_string_);

  if (command_line_string_.empty())
    return;

  int num_args = 0;
  wchar_t** args = NULL;

  args = CommandLineToArgvW(command_line_string_.c_str(), &num_args);

  // Populate program_ with the trimmed version of the first arg.
  TrimWhitespace(args[0], TRIM_ALL, &program_);

  bool parse_switches = true;
  for (int i = 1; i < num_args; ++i) {
    std::wstring arg;
    TrimWhitespace(args[i], TRIM_ALL, &arg);

    if (!parse_switches) {
      args_.push_back(arg);
      continue;
    }

    if (arg == kSwitchTerminator) {
      parse_switches = false;
      continue;
    }

    std::string switch_string;
    std::wstring switch_value;
    if (IsSwitch(arg, &switch_string, &switch_value)) {
      switches_[switch_string] = switch_value;
    } else {
      args_.push_back(arg);
    }
  }

  if (args)
    LocalFree(args);
}
#endif

CommandLine::CommandLine() {
}
