// Copyright (c) 2013 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 <algorithm>
#include <iostream>

#include "base/command_line.h"
#include "tools/gn/args.h"
#include "tools/gn/commands.h"
#include "tools/gn/err.h"
#include "tools/gn/functions.h"
#include "tools/gn/input_conversion.h"
#include "tools/gn/label.h"
#include "tools/gn/label_pattern.h"
#include "tools/gn/ninja_build_writer.h"
#include "tools/gn/output_conversion.h"
#include "tools/gn/parser.h"
#include "tools/gn/runtime_deps.h"
#include "tools/gn/setup.h"
#include "tools/gn/standard_out.h"
#include "tools/gn/string_utils.h"
#include "tools/gn/substitution_writer.h"
#include "tools/gn/switches.h"
#include "tools/gn/target.h"
#include "tools/gn/variables.h"

namespace commands {

namespace {

// Some names exist in multiple sections, these prefixes are used for the
// internal links to disambiguate when writing markdown.
const char kCommandLinkPrefix[] = "cmd_";
const char kFunctionLinkPrefix[] = "func_";
const char kVariableLinkPrefix[] = "var_";

void PrintToplevelHelp() {
  PrintSectionHelp("Commands", "<command>", "commands");
  for (const auto& cmd : commands::GetCommands())
    PrintShortHelp(cmd.second.help_short, kCommandLinkPrefix + cmd.first);

  // Target declarations.
  PrintSectionHelp("Target declarations", "<function>", "targets");
  for (const auto& func : functions::GetFunctions()) {
    if (func.second.is_target)
      PrintShortHelp(func.second.help_short, kFunctionLinkPrefix + func.first);
  }

  // Functions.
  PrintSectionHelp("Buildfile functions", "<function>", "functions");
  for (const auto& func : functions::GetFunctions()) {
    if (!func.second.is_target)
      PrintShortHelp(func.second.help_short, kFunctionLinkPrefix + func.first);
  }

  // Built-in variables.
  PrintSectionHelp("Built-in predefined variables", "<variable>",
                   "predefined_variables");
  for (const auto& builtin : variables::GetBuiltinVariables()) {
    PrintShortHelp(builtin.second.help_short,
                   kVariableLinkPrefix + builtin.first);
  }

  // Target variables.
  PrintSectionHelp("Variables you set in targets", "<variable>",
                   "target_variables");
  for (const auto& target : variables::GetTargetVariables()) {
    PrintShortHelp(target.second.help_short,
                   kVariableLinkPrefix + target.first);
  }

  PrintSectionHelp("Other help topics", "", "other");
  PrintShortHelp("all: Print all the help at once");
  PrintShortHelp("buildargs: How build arguments work.", "buildargs");
  PrintShortHelp("dotfile: Info about the toplevel .gn file.", "dotfile");
  PrintShortHelp("execution: Build graph and execution overview.", "execution");
  PrintShortHelp("grammar: Language and grammar for GN build files.",
                 "grammar");
  PrintShortHelp(
      "input_conversion: Processing input from exec_script and read_file.",
      "input_conversion");
  PrintShortHelp("label_pattern: Matching more than one label.",
                 "label_pattern");
  PrintShortHelp("labels: About labels.", "labels");
  PrintShortHelp("ninja_rules: How Ninja build rules are named.",
                 "ninja_rules");
  PrintShortHelp("nogncheck: Annotating includes for checking.", "nogncheck");
  PrintShortHelp(
      "output_conversion: Specifies how to transform a value to output.",
      "output_conversion");
  PrintShortHelp("runtime_deps: How runtime dependency computation works.",
                 "runtime_deps");
  PrintShortHelp("source_expansion: Map sources to outputs for scripts.",
                 "source_expansion");
  PrintShortHelp("switches: Show available command-line switches.", "switch_list");
}

void PrintSwitchHelp() {
  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
  bool is_markdown = cmdline->HasSwitch(switches::kMarkdown);

  // This uses "switch_list" for the tag because Markdown seems to generate
  // implicit tags for headings that match the strings, and some headings are
  // labeled "switches".
  PrintLongHelp(R"(Available global switches

  Do "gn help --the_switch_you_want_help_on" for more. Individual commands may
  take command-specific switches not listed here. See the help on your specific
  command for more.
)", "switch_list");

  if (is_markdown)
    OutputString("```\n", DECORATION_NONE);

  for (const auto& s : switches::GetSwitches())
    PrintShortHelp(s.second.short_help);

  if (is_markdown)
    OutputString("```\n", DECORATION_NONE);

  OutputString("\n");
}

void PrintAllHelp() {
  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
  bool is_markdown = cmdline->HasSwitch(switches::kMarkdown);

  if (is_markdown) {
    OutputString("# GN Reference\n\n");
    OutputString(
        "*This page is automatically generated from* "
        "`gn help --markdown all`.\n\n");

    // Generate our own table of contents so that we have more control
    // over what's in and out.
    OutputString("## Contents\n\n");
  }

  PrintToplevelHelp();

  OutputString("\n");

  if (is_markdown) {
    OutputString("## <a name=\"commands\"></a>Commands\n\n", DECORATION_NONE,
                 NO_ESCAPING);
  }
  for (const auto& c : commands::GetCommands())
    PrintLongHelp(c.second.help, kCommandLinkPrefix + c.first);

  if (is_markdown) {
    OutputString("## <a name=\"targets\"></a>Target declarations\n\n",
                 DECORATION_NONE, NO_ESCAPING);
  }
  for (const auto& f : functions::GetFunctions()) {
    if (f.second.is_target)
      PrintLongHelp(f.second.help, kFunctionLinkPrefix + f.first);
  }

  if (is_markdown) {
    OutputString("## <a name=\"functions\"></a>Buildfile functions\n\n",
                 DECORATION_NONE, NO_ESCAPING);
  }
  for (const auto& f : functions::GetFunctions()) {
    if (!f.second.is_target)
      PrintLongHelp(f.second.help, kFunctionLinkPrefix + f.first);
  }

  if (is_markdown) {
    OutputString(
        "## <a name=\"predefined_variables\"></a>"
        "Built-in predefined variables\n\n",
        DECORATION_NONE, NO_ESCAPING);
  }
  for (const auto& v : variables::GetBuiltinVariables())
    PrintLongHelp(v.second.help, kVariableLinkPrefix + v.first);

  if (is_markdown) {
    OutputString(
        "## <a name=\"target_variables\"></a>"
        "Variables you set in targets\n\n",
        DECORATION_NONE, NO_ESCAPING);
  }
  for (const auto& v : variables::GetTargetVariables())
    PrintLongHelp(v.second.help, kVariableLinkPrefix + v.first);

  if (is_markdown) {
    OutputString("## <a name=\"other\"></a>Other help topics\n\n",
                 DECORATION_NONE, NO_ESCAPING);
  }
  PrintLongHelp(kBuildArgs_Help, "buildargs");
  PrintLongHelp(kDotfile_Help, "dotfile");
  PrintLongHelp(kExecution_Help, "execution");
  PrintLongHelp(kGrammar_Help, "grammar");
  PrintLongHelp(kInputOutputConversion_Help, "input_conversion");
  PrintLongHelp(kLabelPattern_Help, "label_pattern");
  PrintLongHelp(kLabels_Help, "labels");
  PrintLongHelp(kNinjaRules_Help, "ninja_rules");
  PrintLongHelp(kNoGnCheck_Help, "nogncheck");
  PrintLongHelp(kInputOutputConversion_Help, "output_conversion");
  PrintLongHelp(kRuntimeDeps_Help, "runtime_deps");
  PrintLongHelp(kSourceExpansion_Help, "source_expansion");

  PrintSwitchHelp();
}

// Prints help on the given switch. There should be no leading hyphens. Returns
// true if the switch was found and help was printed. False means the switch is
// unknown.
bool PrintHelpOnSwitch(const std::string& what) {
  const switches::SwitchInfoMap& all = switches::GetSwitches();
  switches::SwitchInfoMap::const_iterator found =
      all.find(base::StringPiece(what));
  if (found == all.end())
    return false;
  PrintLongHelp(found->second.long_help);
  return true;
}

// Special-case help for ambiguous "args" case.
void PrintArgsHelp() {
  PrintLongHelp(
      "The string \"args\" is both a command and a variable for action "
      "targets.\nShowing help for both...\n\n");
  PrintLongHelp(commands::kArgs_Help);
  PrintLongHelp(
      "\n----------------------------------------------------------------------"
      "---------\n\n");
  PrintLongHelp(variables::kArgs_Help);
}

}  // namespace

const char kHelp[] = "help";
const char kHelp_HelpShort[] = "help: Does what you think.";
const char kHelp_Help[] =
    R"(gn help <anything>

  Yo dawg, I heard you like help on your help so I put help on the help in the
  help.

  You can also use "all" as the parameter to get all help at once.

Switches

  --markdown
      Format output in markdown syntax.

Example

  gn help --markdown all
      Dump all help to stdout in markdown format.
)";

int RunHelp(const std::vector<std::string>& args) {
  std::string what;
  if (args.size() == 0) {
    // If no argument is specified, check for switches to allow things like
    // "gn help --args" for help on the args switch.
    const base::CommandLine::SwitchMap& switches =
        base::CommandLine::ForCurrentProcess()->GetSwitches();
    if (switches.empty()) {
      // Still nothing, show help overview.
      PrintToplevelHelp();
      return 0;
    }

    // Switch help needs to be done separately. The CommandLine will strip the
    // switch separators so --args will come out as "args" which is then
    // ambiguous with the variable named "args".
    if (!PrintHelpOnSwitch(switches.begin()->first))
      PrintToplevelHelp();
    return 0;
  } else {
    what = args[0];
  }

  std::vector<base::StringPiece> all_help_topics;

  // Special-case ambiguous topics.
  if (what == "args") {
    PrintArgsHelp();
    return 0;
  }

  // Check commands.
  const commands::CommandInfoMap& command_map = commands::GetCommands();
  auto found_command = command_map.find(what);
  if (found_command != command_map.end()) {
    PrintLongHelp(found_command->second.help);
    return 0;
  }
  for (const auto& entry : command_map)
    all_help_topics.push_back(entry.first);

  // Check functions.
  const functions::FunctionInfoMap& function_map = functions::GetFunctions();
  auto found_function = function_map.find(what);
  if (found_function != function_map.end())
    PrintLongHelp(found_function->second.help);
  for (const auto& entry : function_map)
    all_help_topics.push_back(entry.first);

  // Builtin variables.
  const variables::VariableInfoMap& builtin_vars =
      variables::GetBuiltinVariables();
  auto found_builtin_var = builtin_vars.find(what);
  if (found_builtin_var != builtin_vars.end())
    PrintLongHelp(found_builtin_var->second.help);
  for (const auto& entry : builtin_vars)
    all_help_topics.push_back(entry.first);

  // Target variables.
  const variables::VariableInfoMap& target_vars =
      variables::GetTargetVariables();
  auto found_target_var = target_vars.find(what);
  if (found_target_var != target_vars.end())
    PrintLongHelp(found_target_var->second.help);
  for (const auto& entry : target_vars)
    all_help_topics.push_back(entry.first);

  if (found_function != function_map.end() ||
      found_builtin_var != builtin_vars.end() ||
      found_target_var != target_vars.end())
    return 0;

  // Random other topics.
  std::map<std::string, void (*)()> random_topics;
  random_topics["all"] = PrintAllHelp;
  random_topics["execution"] = []() { PrintLongHelp(kExecution_Help); };
  random_topics["buildargs"] = []() { PrintLongHelp(kBuildArgs_Help); };
  random_topics["dotfile"] = []() { PrintLongHelp(kDotfile_Help); };
  random_topics["grammar"] = []() { PrintLongHelp(kGrammar_Help); };
  random_topics["input_conversion"] = []() {
    PrintLongHelp(kInputOutputConversion_Help);
  };
  random_topics["label_pattern"] = []() { PrintLongHelp(kLabelPattern_Help); };
  random_topics["labels"] = []() { PrintLongHelp(kLabels_Help); };
  random_topics["ninja_rules"] = []() { PrintLongHelp(kNinjaRules_Help); };
  random_topics["nogncheck"] = []() { PrintLongHelp(kNoGnCheck_Help); };
  random_topics["output_conversion"] = []() {
    PrintLongHelp(kInputOutputConversion_Help);
  };
  random_topics["runtime_deps"] = []() { PrintLongHelp(kRuntimeDeps_Help); };
  random_topics["source_expansion"] = []() {
    PrintLongHelp(kSourceExpansion_Help);
  };
  random_topics["switches"] = PrintSwitchHelp;
  auto found_random_topic = random_topics.find(what);
  if (found_random_topic != random_topics.end()) {
    found_random_topic->second();
    return 0;
  }
  for (const auto& entry : random_topics)
    all_help_topics.push_back(entry.first);

  // No help on this.
  Err(Location(), "No help on \"" + what + "\".").PrintToStdout();
  base::StringPiece suggestion = SpellcheckString(what, all_help_topics);
  if (suggestion.empty()) {
    OutputString("Run `gn help` for a list of available topics.\n",
                 DECORATION_NONE);
  } else {
    OutputString("Did you mean `gn help " + suggestion.as_string() + "`?\n",
                 DECORATION_NONE);
  }
  return 1;
}

}  // namespace commands
