// 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 <stddef.h>

#include <algorithm>
#include <memory>
#include <set>
#include <sstream>

#include "base/command_line.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "tools/gn/commands.h"
#include "tools/gn/config.h"
#include "tools/gn/desc_builder.h"
#include "tools/gn/setup.h"
#include "tools/gn/standard_out.h"
#include "tools/gn/switches.h"
#include "tools/gn/target.h"
#include "tools/gn/variables.h"

namespace commands {

namespace {

// Desc-specific command line switches.
const char kBlame[] = "blame";
const char kTree[] = "tree";
const char kAll[] = "all";

void PrintDictValue(const base::Value* value,
                    int indentLevel,
                    bool use_first_indent) {
  std::string indent(indentLevel * 2, ' ');
  const base::ListValue* list_value = nullptr;
  const base::DictionaryValue* dict_value = nullptr;
  std::string string_value;
  bool bool_value = false;
  int int_value = 0;
  if (use_first_indent)
    OutputString(indent);
  if (value->GetAsList(&list_value)) {
    OutputString("[\n");
    bool first = true;
    for (const auto& v : *list_value) {
      if (!first)
        OutputString(",\n");
      PrintDictValue(&v, indentLevel + 1, true);
      first = false;
    }
    OutputString("\n" + indent + "]");
  } else if (value->GetAsString(&string_value)) {
    OutputString("\"" + string_value + "\"");
  } else if (value->GetAsBoolean(&bool_value)) {
    OutputString(bool_value ? "true" : "false");
  } else if (value->GetAsDictionary(&dict_value)) {
    OutputString("{\n");
    std::string indent_plus_one((indentLevel + 1) * 2, ' ');
    base::DictionaryValue::Iterator iter(*dict_value);
    bool first = true;
    while (!iter.IsAtEnd()) {
      if (!first)
        OutputString(",\n");
      OutputString(indent_plus_one + iter.key() + " = ");
      PrintDictValue(&iter.value(), indentLevel + 1, false);
      iter.Advance();
      first = false;
    }
    OutputString("\n" + indent + "}");
  } else if (value->GetAsInteger(&int_value)) {
    OutputString(base::IntToString(int_value));
  } else if (value->is_none()) {
    OutputString("<null>");
  }
}

// Prints value with specified indentation level
void PrintValue(const base::Value* value, int indentLevel) {
  std::string indent(indentLevel * 2, ' ');
  const base::ListValue* list_value = nullptr;
  const base::DictionaryValue* dict_value = nullptr;
  std::string string_value;
  bool bool_value = false;
  int int_value = 0;
  if (value->GetAsList(&list_value)) {
    for (const auto& v : *list_value) {
      PrintValue(&v, indentLevel);
    }
  } else if (value->GetAsString(&string_value)) {
    OutputString(indent);
    OutputString(string_value);
    OutputString("\n");
  } else if (value->GetAsBoolean(&bool_value)) {
    OutputString(indent);
    OutputString(bool_value ? "true" : "false");
    OutputString("\n");
  } else if (value->GetAsDictionary(&dict_value)) {
    base::DictionaryValue::Iterator iter(*dict_value);
    while (!iter.IsAtEnd()) {
      OutputString(indent + iter.key() + "\n");
      PrintValue(&iter.value(), indentLevel + 1);
      iter.Advance();
    }
  } else if (value->GetAsInteger(&int_value)) {
    OutputString(indent);
    OutputString(base::IntToString(int_value));
    OutputString("\n");
  } else if (value->is_none()) {
    OutputString(indent + "<null>\n");
  }
}

// Default handler for property
void DefaultHandler(const std::string& name,
                    const base::Value* value,
                    bool value_only) {
  if (value_only) {
    PrintValue(value, 0);
    return;
  }
  OutputString("\n");
  OutputString(name);
  OutputString("\n");
  PrintValue(value, 1);
}

// Specific handler for properties that need different treatment

// Prints the dict in GN scope-sytle.
void MetadataHandler(const std::string& name,
                     const base::Value* value,
                     bool value_only) {
  if (value_only) {
    PrintDictValue(value, 0, true);
    OutputString("\n");
    return;
  }
  OutputString("\n");
  OutputString(name);
  OutputString("\n");
  PrintDictValue(value, 1, true);
  OutputString("\n");
}

// Prints label and property value on one line, capitalizing the label.
void LabelHandler(const std::string& name,
                  const base::Value* value,
                  bool value_only) {
  if (value_only) {
    PrintValue(value, 0);
    return;
  }
  std::string label = name;
  label[0] = base::ToUpperASCII(label[0]);
  std::string string_value;
  if (value->GetAsString(&string_value)) {
    OutputString(name + ": ", DECORATION_YELLOW);
    OutputString(string_value + "\n");
  }
}

void VisibilityHandler(const std::string& name,
                       const base::Value* value,
                       bool value_only) {
  if (value_only) {
    PrintValue(value, 0);
    return;
  }
  const base::ListValue* list;
  if (value->GetAsList(&list)) {
    if (list->empty()) {
      base::Value str("(no visibility)");
      DefaultHandler(name, &str, value_only);
    } else {
      DefaultHandler(name, value, value_only);
    }
  }
}

void PublicHandler(const std::string& name,
                   const base::Value* value,
                   bool value_only) {
  if (value_only) {
    PrintValue(value, 0);
    return;
  }
  std::string p;
  if (value->GetAsString(&p)) {
    if (p == "*") {
      base::Value str("[All headers listed in the sources are public.]");
      DefaultHandler(name, &str, value_only);
      return;
    }
  }
  DefaultHandler(name, value, value_only);
}

void ConfigsHandler(const std::string& name,
                    const base::Value* value,
                    bool value_only) {
  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
  if (tree)
    DefaultHandler(name + " tree (in order applying)", value, value_only);
  else
    DefaultHandler(name + " (in order applying, try also --tree)", value,
                   value_only);
}

void DepsHandler(const std::string& name,
                 const base::Value* value,
                 bool value_only) {
  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
  bool all = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
  if (tree) {
    DefaultHandler("Dependency tree", value, value_only);
  } else {
    if (!all) {
      DefaultHandler(
          "Direct dependencies "
          "(try also \"--all\", \"--tree\", or even \"--all --tree\")",
          value, value_only);
    } else {
      DefaultHandler("All recursive dependencies", value, value_only);
    }
  }
}

// Outputs need special processing when output patterns are present.
void ProcessOutputs(base::DictionaryValue* target, bool files_only) {
  base::ListValue* patterns = nullptr;
  base::ListValue* outputs = nullptr;
  target->GetList("output_patterns", &patterns);
  target->GetList(variables::kOutputs, &outputs);

  int indent = 0;
  if (outputs || patterns) {
    if (!files_only) {
      OutputString("\noutputs\n");
      indent = 1;
    }
    if (patterns) {
      if (!files_only) {
        OutputString("  Output patterns\n");
        indent = 2;
      }
      PrintValue(patterns, indent);
      if (!files_only)
        OutputString("\n  Resolved output file list\n");
    }
    if (outputs)
      PrintValue(outputs, indent);

    target->Remove("output_patterns", nullptr);
    target->Remove(variables::kOutputs, nullptr);
  }
}

using DescHandlerFunc = void (*)(const std::string& name,
                                 const base::Value* value,
                                 bool value_only);
std::map<std::string, DescHandlerFunc> GetHandlers() {
  return {{"type", LabelHandler},
          {"toolchain", LabelHandler},
          {variables::kVisibility, VisibilityHandler},
          {variables::kMetadata, MetadataHandler},
          {variables::kTestonly, DefaultHandler},
          {variables::kCheckIncludes, DefaultHandler},
          {variables::kAllowCircularIncludesFrom, DefaultHandler},
          {variables::kSources, DefaultHandler},
          {variables::kPublic, PublicHandler},
          {variables::kInputs, DefaultHandler},
          {variables::kConfigs, ConfigsHandler},
          {variables::kPublicConfigs, ConfigsHandler},
          {variables::kAllDependentConfigs, ConfigsHandler},
          {variables::kScript, DefaultHandler},
          {variables::kArgs, DefaultHandler},
          {variables::kDepfile, DefaultHandler},
          {"bundle_data", DefaultHandler},
          {variables::kArflags, DefaultHandler},
          {variables::kAsmflags, DefaultHandler},
          {variables::kCflags, DefaultHandler},
          {variables::kCflagsC, DefaultHandler},
          {variables::kCflagsCC, DefaultHandler},
          {variables::kCflagsObjC, DefaultHandler},
          {variables::kCflagsObjCC, DefaultHandler},
          {variables::kDefines, DefaultHandler},
          {variables::kIncludeDirs, DefaultHandler},
          {variables::kLdflags, DefaultHandler},
          {variables::kPrecompiledHeader, DefaultHandler},
          {variables::kPrecompiledSource, DefaultHandler},
          {variables::kDeps, DepsHandler},
          {variables::kLibs, DefaultHandler},
          {variables::kLibDirs, DefaultHandler},
          {variables::kDataKeys, DefaultHandler},
          {variables::kRebase, DefaultHandler},
          {variables::kWalkKeys, DefaultHandler},
          {variables::kWriteOutputConversion, DefaultHandler},
          {"runtime_deps", DefaultHandler}};
}

void HandleProperty(const std::string& what,
                    const std::map<std::string, DescHandlerFunc>& handler_map,
                    std::unique_ptr<base::Value>& v,
                    std::unique_ptr<base::DictionaryValue>& dict) {
  if (dict->Remove(what, &v)) {
    auto pair = handler_map.find(what);
    if (pair != handler_map.end())
      pair->second(what, v.get(), false);
  }
}

bool PrintTarget(const Target* target,
                 const std::string& what,
                 bool single_target,
                 const std::map<std::string, DescHandlerFunc>& handler_map,
                 bool all,
                 bool tree,
                 bool blame) {
  std::unique_ptr<base::DictionaryValue> dict =
      DescBuilder::DescriptionForTarget(target, what, all, tree, blame);
  if (!what.empty() && dict->empty()) {
    OutputString("Don't know how to display \"" + what + "\" for \"" +
                 Target::GetStringForOutputType(target->output_type()) +
                 "\".\n");
    return false;
  }
  // Print single value
  if (!what.empty() && dict->size() == 1 && single_target) {
    if (what == variables::kOutputs) {
      ProcessOutputs(dict.get(), true);
      return true;
    }
    base::DictionaryValue::Iterator iter(*dict);
    auto pair = handler_map.find(what);
    if (pair != handler_map.end())
      pair->second(what, &iter.value(), true);
    return true;
  }

  OutputString("Target ", DECORATION_YELLOW);
  OutputString(target->label().GetUserVisibleName(false));
  OutputString("\n");

  std::unique_ptr<base::Value> v;
  // Entries with DefaultHandler are present to enforce order
  HandleProperty("type", handler_map, v, dict);
  HandleProperty("toolchain", handler_map, v, dict);
  HandleProperty(variables::kVisibility, handler_map, v, dict);
  HandleProperty(variables::kMetadata, handler_map, v, dict);
  HandleProperty(variables::kTestonly, handler_map, v, dict);
  HandleProperty(variables::kCheckIncludes, handler_map, v, dict);
  HandleProperty(variables::kAllowCircularIncludesFrom, handler_map, v, dict);
  HandleProperty(variables::kSources, handler_map, v, dict);
  HandleProperty(variables::kPublic, handler_map, v, dict);
  HandleProperty(variables::kInputs, handler_map, v, dict);
  HandleProperty(variables::kConfigs, handler_map, v, dict);
  HandleProperty(variables::kPublicConfigs, handler_map, v, dict);
  HandleProperty(variables::kAllDependentConfigs, handler_map, v, dict);
  HandleProperty(variables::kScript, handler_map, v, dict);
  HandleProperty(variables::kArgs, handler_map, v, dict);
  HandleProperty(variables::kDepfile, handler_map, v, dict);
  ProcessOutputs(dict.get(), false);
  HandleProperty("bundle_data", handler_map, v, dict);
  HandleProperty(variables::kArflags, handler_map, v, dict);
  HandleProperty(variables::kAsmflags, handler_map, v, dict);
  HandleProperty(variables::kCflags, handler_map, v, dict);
  HandleProperty(variables::kCflagsC, handler_map, v, dict);
  HandleProperty(variables::kCflagsCC, handler_map, v, dict);
  HandleProperty(variables::kCflagsObjC, handler_map, v, dict);
  HandleProperty(variables::kCflagsObjCC, handler_map, v, dict);
  HandleProperty(variables::kDefines, handler_map, v, dict);
  HandleProperty(variables::kIncludeDirs, handler_map, v, dict);
  HandleProperty(variables::kLdflags, handler_map, v, dict);
  HandleProperty(variables::kPrecompiledHeader, handler_map, v, dict);
  HandleProperty(variables::kPrecompiledSource, handler_map, v, dict);
  HandleProperty(variables::kDeps, handler_map, v, dict);
  HandleProperty(variables::kLibs, handler_map, v, dict);
  HandleProperty(variables::kLibDirs, handler_map, v, dict);
  HandleProperty(variables::kDataKeys, handler_map, v, dict);
  HandleProperty(variables::kRebase, handler_map, v, dict);
  HandleProperty(variables::kWalkKeys, handler_map, v, dict);
  HandleProperty(variables::kWriteOutputConversion, handler_map, v, dict);

#undef HandleProperty

  // Process the rest (if any)
  base::DictionaryValue::Iterator iter(*dict);
  while (!iter.IsAtEnd()) {
    DefaultHandler(iter.key(), &iter.value(), false);
    iter.Advance();
  }

  return true;
}

bool PrintConfig(const Config* config,
                 const std::string& what,
                 bool single_config,
                 const std::map<std::string, DescHandlerFunc>& handler_map) {
  std::unique_ptr<base::DictionaryValue> dict =
      DescBuilder::DescriptionForConfig(config, what);
  if (!what.empty() && dict->empty()) {
    OutputString("Don't know how to display \"" + what + "\" for a config.\n");
    return false;
  }
  // Print single value
  if (!what.empty() && dict->size() == 1 && single_config) {
    base::DictionaryValue::Iterator iter(*dict);
    auto pair = handler_map.find(what);
    if (pair != handler_map.end())
      pair->second(what, &iter.value(), true);
    return true;
  }

  OutputString("Config: ", DECORATION_YELLOW);
  OutputString(config->label().GetUserVisibleName(false));
  OutputString("\n");

  std::unique_ptr<base::Value> v;
  HandleProperty("toolchain", handler_map, v, dict);
  if (!config->configs().empty()) {
    OutputString(
        "(This is a composite config, the values below are after the\n"
        "expansion of the child configs.)\n");
  }
  HandleProperty(variables::kArflags, handler_map, v, dict);
  HandleProperty(variables::kAsmflags, handler_map, v, dict);
  HandleProperty(variables::kCflags, handler_map, v, dict);
  HandleProperty(variables::kCflagsC, handler_map, v, dict);
  HandleProperty(variables::kCflagsCC, handler_map, v, dict);
  HandleProperty(variables::kCflagsObjC, handler_map, v, dict);
  HandleProperty(variables::kCflagsObjCC, handler_map, v, dict);
  HandleProperty(variables::kDefines, handler_map, v, dict);
  HandleProperty(variables::kIncludeDirs, handler_map, v, dict);
  HandleProperty(variables::kInputs, handler_map, v, dict);
  HandleProperty(variables::kLdflags, handler_map, v, dict);
  HandleProperty(variables::kLibs, handler_map, v, dict);
  HandleProperty(variables::kLibDirs, handler_map, v, dict);
  HandleProperty(variables::kPrecompiledHeader, handler_map, v, dict);
  HandleProperty(variables::kPrecompiledSource, handler_map, v, dict);

#undef HandleProperty

  return true;
}

}  // namespace

// desc ------------------------------------------------------------------------

const char kDesc[] = "desc";
const char kDesc_HelpShort[] =
    "desc: Show lots of insightful information about a target or config.";
const char kDesc_Help[] =
    R"(gn desc

  gn desc <out_dir> <label or pattern> [<what to show>] [--blame]
          [--format=json]

  Displays information about a given target or config. The build parameters
  will be taken for the build in the given <out_dir>.

  The <label or pattern> can be a target label, a config label, or a label
  pattern (see "gn help label_pattern"). A label pattern will only match
  targets.

Possibilities for <what to show>

  (If unspecified an overall summary will be displayed.)

  all_dependent_configs
  allow_circular_includes_from
  arflags [--blame]
  args
  cflags [--blame]
  cflags_c [--blame]
  cflags_cc [--blame]
  check_includes
  configs [--tree] (see below)
  data_keys
  defines [--blame]
  depfile
  deps [--all] [--tree] (see below)
  include_dirs [--blame]
  inputs
  ldflags [--blame]
  lib_dirs
  libs
  metadata
  output_conversion
  outputs
  public_configs
  public
  rebase
  script
  sources
  testonly
  visibility
  walk_keys

  runtime_deps
      Compute all runtime deps for the given target. This is a computed list
      and does not correspond to any GN variable, unlike most other values
      here.

      The output is a list of file names relative to the build directory. See
      "gn help runtime_deps" for how this is computed. This also works with
      "--blame" to see the source of the dependency.

Shared flags
)"

    ALL_TOOLCHAINS_SWITCH_HELP

    R"(
  --format=json
      Format the output as JSON instead of text.

Target flags

  --blame
      Used with any value specified on a config, this will name the config that
      causes that target to get the flag. This doesn't currently work for libs
      and lib_dirs because those are inherited and are more complicated to
      figure out the blame (patches welcome).

Configs

  The "configs" section will list all configs that apply. For targets this will
  include configs specified in the "configs" variable of the target, and also
  configs pushed onto this target via public or "all dependent" configs.

  Configs can have child configs. Specifying --tree will show the hierarchy.

Printing outputs

  The "outputs" section will list all outputs that apply, including the outputs
  computed from the tool definition (eg for "executable", "static_library", ...
  targets).

Printing deps

  Deps will include all public, private, and data deps (TODO this could be
  clarified and enhanced) sorted in order applying. The following may be used:

  --all
      Collects all recursive dependencies and prints a sorted flat list. Also
      usable with --tree (see below).
)"

    TARGET_PRINTING_MODE_COMMAND_LINE_HELP
    "\n" TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP

    R"(
  --tree
      Print a dependency tree. By default, duplicates will be elided with "..."
      but when --all and -tree are used together, no eliding will be performed.

      The "deps", "public_deps", and "data_deps" will all be included in the
      tree.

      Tree output can not be used with the filtering or output flags: --as,
      --type, --testonly.
)"

    TARGET_TYPE_FILTER_COMMAND_LINE_HELP

    R"(Note

  This command will show the full name of directories and source files, but
  when directories and source paths are written to the build file, they will be
  adjusted to be relative to the build directory. So the values for paths
  displayed by this command won't match (but should mean the same thing).

Examples

  gn desc out/Debug //base:base
      Summarizes the given target.

  gn desc out/Foo :base_unittests deps --tree
      Shows a dependency tree of the "base_unittests" project in
      the current directory.

  gn desc out/Debug //base defines --blame
      Shows defines set for the //base:base target, annotated by where
      each one was set from.
)";

int RunDesc(const std::vector<std::string>& args) {
  if (args.size() != 2 && args.size() != 3) {
    Err(Location(), "You're holding it wrong.",
        "Usage: \"gn desc <out_dir> <target_name> [<what to display>]\"")
        .PrintToStdout();
    return 1;
  }
  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();

  // Deliberately leaked to avoid expensive process teardown.
  Setup* setup = new Setup;
  if (!setup->DoSetup(args[0], false))
    return 1;
  if (!setup->Run())
    return 1;

  // Resolve target(s) and config from inputs.
  UniqueVector<const Target*> target_matches;
  UniqueVector<const Config*> config_matches;
  UniqueVector<const Toolchain*> toolchain_matches;
  UniqueVector<SourceFile> file_matches;

  std::vector<std::string> target_list;
  target_list.push_back(args[1]);

  if (!ResolveFromCommandLineInput(
          setup, target_list, cmdline->HasSwitch(switches::kAllToolchains),
          &target_matches, &config_matches, &toolchain_matches, &file_matches))
    return 1;

  std::string what_to_print;
  if (args.size() == 3)
    what_to_print = args[2];

  bool json = cmdline->GetSwitchValueASCII("format") == "json";

  if (target_matches.empty() && config_matches.empty()) {
    OutputString(
        "The input " + args[1] + " matches no targets, configs or files.\n",
        DECORATION_YELLOW);
    return 1;
  }

  if (json) {
    // Convert all targets/configs to JSON, serialize and print them
    auto res = std::make_unique<base::DictionaryValue>();
    if (!target_matches.empty()) {
      for (const auto* target : target_matches) {
        res->SetWithoutPathExpansion(
            target->label().GetUserVisibleName(
                target->settings()->default_toolchain_label()),
            DescBuilder::DescriptionForTarget(
                target, what_to_print, cmdline->HasSwitch(kAll),
                cmdline->HasSwitch(kTree), cmdline->HasSwitch(kBlame)));
      }
    } else if (!config_matches.empty()) {
      for (const auto* config : config_matches) {
        res->SetWithoutPathExpansion(
            config->label().GetUserVisibleName(false),
            DescBuilder::DescriptionForConfig(config, what_to_print));
      }
    }
    std::string s;
    base::JSONWriter::WriteWithOptions(
        *res.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &s);
    OutputString(s);
  } else {
    // Regular (non-json) formatted output
    bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1;
    std::map<std::string, DescHandlerFunc> handlers = GetHandlers();

    bool printed_output = false;
    for (const Target* target : target_matches) {
      if (printed_output)
        OutputString("\n\n");
      printed_output = true;

      if (!PrintTarget(target, what_to_print, !multiple_outputs, handlers,
                       cmdline->HasSwitch(kAll), cmdline->HasSwitch(kTree),
                       cmdline->HasSwitch(kBlame)))
        return 1;
    }
    for (const Config* config : config_matches) {
      if (printed_output)
        OutputString("\n\n");
      printed_output = true;

      if (!PrintConfig(config, what_to_print, !multiple_outputs, handlers))
        return 1;
    }
  }

  return 0;
}

}  // namespace commands
