// Copyright 2014 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 "tools/gn/substitution_writer.h"

#include "tools/gn/build_settings.h"
#include "tools/gn/escape.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/output_file.h"
#include "tools/gn/settings.h"
#include "tools/gn/source_file.h"
#include "tools/gn/string_utils.h"
#include "tools/gn/substitution_list.h"
#include "tools/gn/substitution_pattern.h"
#include "tools/gn/target.h"

namespace {

// Sets the given directory string to the destination, trimming any trailing
// slash from the directory (SourceDirs and OutputFiles representing
// directories will end in a trailing slash). If the directory is empty,
// it will be replaced with a ".".
void SetDirOrDotWithNoSlash(const std::string& dir, std::string* dest) {
  if (!dir.empty() && dir[dir.size() - 1] == '/')
    dest->assign(dir.data(), dir.size() - 1);
  else
    dest->assign(dir);

  if (dest->empty())
    dest->push_back('.');
}

}  // namespace

const char kSourceExpansion_Help[] =
    R"(How Source Expansion Works

  Source expansion is used for the action_foreach and copy target types to map
  source file names to output file names or arguments.

  To perform source expansion in the outputs, GN maps every entry in the
  sources to every entry in the outputs list, producing the cross product of
  all combinations, expanding placeholders (see below).

  Source expansion in the args works similarly, but performing the placeholder
  substitution produces a different set of arguments for each invocation of the
  script.

  If no placeholders are found, the outputs or args list will be treated as a
  static list of literal file names that do not depend on the sources.

  See "gn help copy" and "gn help action_foreach" for more on how this is
  applied.

Placeholders

  This section discusses only placeholders for actions. There are other
  placeholders used in the definition of tools. See "gn help tool" for those.

  {{source}}
      The name of the source file including directory (*). This will generally
      be used for specifying inputs to a script in the "args" variable.
        "//foo/bar/baz.txt" => "../../foo/bar/baz.txt"

  {{source_file_part}}
      The file part of the source including the extension.
        "//foo/bar/baz.txt" => "baz.txt"

  {{source_name_part}}
      The filename part of the source file with no directory or extension. This
      will generally be used for specifying a transformation from a source file
      to a destination file with the same name but different extension.
        "//foo/bar/baz.txt" => "baz"

  {{source_dir}}
      The directory (*) containing the source file with no trailing slash.
        "//foo/bar/baz.txt" => "../../foo/bar"

  {{source_root_relative_dir}}
      The path to the source file's directory relative to the source root, with
      no leading "//" or trailing slashes. If the path is system-absolute,
      (beginning in a single slash) this will just return the path with no
      trailing slash. This value will always be the same, regardless of whether
      it appears in the "outputs" or "args" section.
        "//foo/bar/baz.txt" => "foo/bar"

  {{source_gen_dir}}
      The generated file directory (*) corresponding to the source file's path.
      This will be different than the target's generated file directory if the
      source file is in a different directory than the BUILD.gn file.
        "//foo/bar/baz.txt" => "gen/foo/bar"

  {{source_out_dir}}
      The object file directory (*) corresponding to the source file's path,
      relative to the build directory. this us be different than the target's
      out directory if the source file is in a different directory than the
      build.gn file.
        "//foo/bar/baz.txt" => "obj/foo/bar"

  {{source_target_relative}}
      The path to the source file relative to the target's directory. This will
      generally be used for replicating the source directory layout in the
      output directory. This can only be used in actions and it is an error to
      use in process_file_template where there is no "target".
        "//foo/bar/baz.txt" => "baz.txt"

(*) Note on directories

  Paths containing directories (except the source_root_relative_dir) will be
  different depending on what context the expansion is evaluated in. Generally
  it should "just work" but it means you can't concatenate strings containing
  these values with reasonable results.

  Details: source expansions can be used in the "outputs" variable, the "args"
  variable, and in calls to "process_file_template". The "args" are passed to a
  script which is run from the build directory, so these directories will
  relative to the build directory for the script to find. In the other cases,
  the directories will be source- absolute (begin with a "//") because the
  results of those expansions will be handled by GN internally.

Examples

  Non-varying outputs:
    action("hardcoded_outputs") {
      sources = [ "input1.idl", "input2.idl" ]
      outputs = [ "$target_out_dir/output1.dat",
                  "$target_out_dir/output2.dat" ]
    }
  The outputs in this case will be the two literal files given.

  Varying outputs:
    action_foreach("varying_outputs") {
      sources = [ "input1.idl", "input2.idl" ]
      outputs = [ "{{source_gen_dir}}/{{source_name_part}}.h",
                  "{{source_gen_dir}}/{{source_name_part}}.cc" ]
    }
  Performing source expansion will result in the following output names:
    //out/Debug/obj/mydirectory/input1.h
    //out/Debug/obj/mydirectory/input1.cc
    //out/Debug/obj/mydirectory/input2.h
    //out/Debug/obj/mydirectory/input2.cc
)";

// static
void SubstitutionWriter::WriteWithNinjaVariables(
    const SubstitutionPattern& pattern,
    const EscapeOptions& escape_options,
    std::ostream& out) {
  // The result needs to be quoted as if it was one string, but the $ for
  // the inserted Ninja variables can't be escaped. So write to a buffer with
  // no quoting, and then quote the whole thing if necessary.
  EscapeOptions no_quoting(escape_options);
  no_quoting.inhibit_quoting = true;

  bool needs_quotes = false;
  std::string result;
  for (const auto& range : pattern.ranges()) {
    if (range.type == SUBSTITUTION_LITERAL) {
      result.append(EscapeString(range.literal, no_quoting, &needs_quotes));
    } else {
      result.append("${");
      result.append(kSubstitutionNinjaNames[range.type]);
      result.append("}");
    }
  }

  if (needs_quotes && !escape_options.inhibit_quoting)
    out << "\"" << result << "\"";
  else
    out << result;
}

// static
void SubstitutionWriter::GetListAsSourceFiles(const SubstitutionList& list,
                                              std::vector<SourceFile>* output) {
  for (const auto& pattern : list.list()) {
    CHECK(pattern.ranges().size() == 1 &&
          pattern.ranges()[0].type == SUBSTITUTION_LITERAL)
        << "The substitution pattern \"" << pattern.AsString()
        << "\" was expected to be a literal with no {{substitutions}}.";
    const std::string& literal = pattern.ranges()[0].literal;
    CHECK(literal.size() >= 1 && literal[0] == '/')
        << "The result of the pattern \"" << pattern.AsString()
        << "\" was not an absolute path.";
    output->push_back(SourceFile(literal));
  }
}

// static
void SubstitutionWriter::GetListAsOutputFiles(const Settings* settings,
                                              const SubstitutionList& list,
                                              std::vector<OutputFile>* output) {
  std::vector<SourceFile> output_as_sources;
  GetListAsSourceFiles(list, &output_as_sources);
  for (const auto& file : output_as_sources)
    output->push_back(OutputFile(settings->build_settings(), file));
}

// static
SourceFile SubstitutionWriter::ApplyPatternToSource(
    const Target* target,
    const Settings* settings,
    const SubstitutionPattern& pattern,
    const SourceFile& source) {
  std::string result_value =
      ApplyPatternToSourceAsString(target, settings, pattern, source);
  CHECK(!result_value.empty() && result_value[0] == '/')
      << "The result of the pattern \"" << pattern.AsString()
      << "\" was not a path beginning in \"/\" or \"//\".";
  return SourceFile(SourceFile::SWAP_IN, &result_value);
}

// static
std::string SubstitutionWriter::ApplyPatternToSourceAsString(
    const Target* target,
    const Settings* settings,
    const SubstitutionPattern& pattern,
    const SourceFile& source) {
  std::string result_value;
  for (const auto& subrange : pattern.ranges()) {
    if (subrange.type == SUBSTITUTION_LITERAL) {
      result_value.append(subrange.literal);
    } else {
      result_value.append(GetSourceSubstitution(target, settings, source,
                                                subrange.type, OUTPUT_ABSOLUTE,
                                                SourceDir()));
    }
  }
  return result_value;
}

// static
OutputFile SubstitutionWriter::ApplyPatternToSourceAsOutputFile(
    const Target* target,
    const Settings* settings,
    const SubstitutionPattern& pattern,
    const SourceFile& source) {
  SourceFile result_as_source =
      ApplyPatternToSource(target, settings, pattern, source);
  return OutputFile(settings->build_settings(), result_as_source);
}

// static
void SubstitutionWriter::ApplyListToSource(const Target* target,
                                           const Settings* settings,
                                           const SubstitutionList& list,
                                           const SourceFile& source,
                                           std::vector<SourceFile>* output) {
  for (const auto& item : list.list())
    output->push_back(ApplyPatternToSource(target, settings, item, source));
}

// static
void SubstitutionWriter::ApplyListToSourceAsString(
    const Target* target,
    const Settings* settings,
    const SubstitutionList& list,
    const SourceFile& source,
    std::vector<std::string>* output) {
  for (const auto& item : list.list())
    output->push_back(
        ApplyPatternToSourceAsString(target, settings, item, source));
}

// static
void SubstitutionWriter::ApplyListToSourceAsOutputFile(
    const Target* target,
    const Settings* settings,
    const SubstitutionList& list,
    const SourceFile& source,
    std::vector<OutputFile>* output) {
  for (const auto& item : list.list())
    output->push_back(
        ApplyPatternToSourceAsOutputFile(target, settings, item, source));
}

// static
void SubstitutionWriter::ApplyListToSources(
    const Target* target,
    const Settings* settings,
    const SubstitutionList& list,
    const std::vector<SourceFile>& sources,
    std::vector<SourceFile>* output) {
  output->clear();
  for (const auto& source : sources)
    ApplyListToSource(target, settings, list, source, output);
}

// static
void SubstitutionWriter::ApplyListToSourcesAsString(
    const Target* target,
    const Settings* settings,
    const SubstitutionList& list,
    const std::vector<SourceFile>& sources,
    std::vector<std::string>* output) {
  output->clear();
  for (const auto& source : sources)
    ApplyListToSourceAsString(target, settings, list, source, output);
}

// static
void SubstitutionWriter::ApplyListToSourcesAsOutputFile(
    const Target* target,
    const Settings* settings,
    const SubstitutionList& list,
    const std::vector<SourceFile>& sources,
    std::vector<OutputFile>* output) {
  output->clear();
  for (const auto& source : sources)
    ApplyListToSourceAsOutputFile(target, settings, list, source, output);
}

// static
void SubstitutionWriter::WriteNinjaVariablesForSource(
    const Target* target,
    const Settings* settings,
    const SourceFile& source,
    const std::vector<SubstitutionType>& types,
    const EscapeOptions& escape_options,
    std::ostream& out) {
  for (const auto& type : types) {
    // Don't write SOURCE since that just maps to Ninja's $in variable, which
    // is implicit in the rule. RESPONSE_FILE_NAME is written separately
    // only when writing target rules since it can never be used in any
    // other context (like process_file_template).
    if (type != SUBSTITUTION_SOURCE && type != SUBSTITUTION_RSP_FILE_NAME) {
      out << "  " << kSubstitutionNinjaNames[type] << " = ";
      EscapeStringToStream(
          out,
          GetSourceSubstitution(target, settings, source, type, OUTPUT_RELATIVE,
                                settings->build_settings()->build_dir()),
          escape_options);
      out << std::endl;
    }
  }
}

// static
std::string SubstitutionWriter::GetSourceSubstitution(
    const Target* target,
    const Settings* settings,
    const SourceFile& source,
    SubstitutionType type,
    OutputStyle output_style,
    const SourceDir& relative_to) {
  std::string to_rebase;
  switch (type) {
    case SUBSTITUTION_SOURCE:
      if (source.is_system_absolute())
        return source.value();
      to_rebase = source.value();
      break;

    case SUBSTITUTION_SOURCE_NAME_PART:
      return FindFilenameNoExtension(&source.value()).as_string();

    case SUBSTITUTION_SOURCE_FILE_PART:
      return source.GetName();

    case SUBSTITUTION_SOURCE_DIR:
      if (source.is_system_absolute())
        return DirectoryWithNoLastSlash(source.GetDir());
      to_rebase = DirectoryWithNoLastSlash(source.GetDir());
      break;

    case SUBSTITUTION_SOURCE_ROOT_RELATIVE_DIR:
      if (source.is_system_absolute())
        return DirectoryWithNoLastSlash(source.GetDir());
      return RebasePath(DirectoryWithNoLastSlash(source.GetDir()),
                        SourceDir("//"),
                        settings->build_settings()->root_path_utf8());

    case SUBSTITUTION_SOURCE_GEN_DIR:
      to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir(
          BuildDirContext(settings), source.GetDir(), BuildDirType::GEN));
      break;

    case SUBSTITUTION_SOURCE_OUT_DIR:
      to_rebase = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir(
          BuildDirContext(settings), source.GetDir(), BuildDirType::OBJ));
      break;

    case SUBSTITUTION_SOURCE_TARGET_RELATIVE:
      if (target) {
        return RebasePath(source.value(), target->label().dir(),
                          settings->build_settings()->root_path_utf8());
      }
      NOTREACHED() << "Cannot use substitution " << kSubstitutionNames[type]
                   << " without target";
      return std::string();

    default:
      NOTREACHED() << "Unsupported substitution for this function: "
                   << kSubstitutionNames[type];
      return std::string();
  }

  // If we get here, the result is a path that should be made relative or
  // absolute according to the output_style. Other cases (just file name or
  // extension extraction) will have been handled via early return above.
  if (output_style == OUTPUT_ABSOLUTE)
    return to_rebase;
  return RebasePath(to_rebase, relative_to,
                    settings->build_settings()->root_path_utf8());
}

// static
OutputFile SubstitutionWriter::ApplyPatternToTargetAsOutputFile(
    const Target* target,
    const Tool* tool,
    const SubstitutionPattern& pattern) {
  std::string result_value;
  for (const auto& subrange : pattern.ranges()) {
    if (subrange.type == SUBSTITUTION_LITERAL) {
      result_value.append(subrange.literal);
    } else {
      std::string subst;
      CHECK(GetTargetSubstitution(target, subrange.type, &subst));
      result_value.append(subst);
    }
  }
  return OutputFile(result_value);
}

// static
void SubstitutionWriter::ApplyListToTargetAsOutputFile(
    const Target* target,
    const Tool* tool,
    const SubstitutionList& list,
    std::vector<OutputFile>* output) {
  for (const auto& item : list.list())
    output->push_back(ApplyPatternToTargetAsOutputFile(target, tool, item));
}

// static
bool SubstitutionWriter::GetTargetSubstitution(const Target* target,
                                               SubstitutionType type,
                                               std::string* result) {
  switch (type) {
    case SUBSTITUTION_LABEL:
      // Only include the toolchain for non-default toolchains.
      *result =
          target->label().GetUserVisibleName(!target->settings()->is_default());
      break;
    case SUBSTITUTION_LABEL_NAME:
      *result = target->label().name();
      break;
    case SUBSTITUTION_ROOT_GEN_DIR:
      SetDirOrDotWithNoSlash(
          GetBuildDirAsOutputFile(BuildDirContext(target), BuildDirType::GEN)
              .value(),
          result);
      break;
    case SUBSTITUTION_ROOT_OUT_DIR:
      SetDirOrDotWithNoSlash(
          target->settings()->toolchain_output_subdir().value(), result);
      break;
    case SUBSTITUTION_TARGET_GEN_DIR:
      SetDirOrDotWithNoSlash(
          GetBuildDirForTargetAsOutputFile(target, BuildDirType::GEN).value(),
          result);
      break;
    case SUBSTITUTION_TARGET_OUT_DIR:
      SetDirOrDotWithNoSlash(
          GetBuildDirForTargetAsOutputFile(target, BuildDirType::OBJ).value(),
          result);
      break;
    case SUBSTITUTION_TARGET_OUTPUT_NAME:
      *result = target->GetComputedOutputName();
      break;
    default:
      return false;
  }
  return true;
}

// static
std::string SubstitutionWriter::GetTargetSubstitution(const Target* target,
                                                      SubstitutionType type) {
  std::string result;
  GetTargetSubstitution(target, type, &result);
  return result;
}

// static
OutputFile SubstitutionWriter::ApplyPatternToCompilerAsOutputFile(
    const Target* target,
    const SourceFile& source,
    const SubstitutionPattern& pattern) {
  OutputFile result;
  for (const auto& subrange : pattern.ranges()) {
    if (subrange.type == SUBSTITUTION_LITERAL) {
      result.value().append(subrange.literal);
    } else {
      result.value().append(
          GetCompilerSubstitution(target, source, subrange.type));
    }
  }
  return result;
}

// static
void SubstitutionWriter::ApplyListToCompilerAsOutputFile(
    const Target* target,
    const SourceFile& source,
    const SubstitutionList& list,
    std::vector<OutputFile>* output) {
  for (const auto& item : list.list())
    output->push_back(ApplyPatternToCompilerAsOutputFile(target, source, item));
}

// static
std::string SubstitutionWriter::GetCompilerSubstitution(
    const Target* target,
    const SourceFile& source,
    SubstitutionType type) {
  // First try the common tool ones.
  std::string result;
  if (GetTargetSubstitution(target, type, &result))
    return result;

  // Fall-through to the source ones.
  return GetSourceSubstitution(
      target, target->settings(), source, type, OUTPUT_RELATIVE,
      target->settings()->build_settings()->build_dir());
}

// static
OutputFile SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
    const Target* target,
    const Tool* tool,
    const SubstitutionPattern& pattern) {
  OutputFile result;
  for (const auto& subrange : pattern.ranges()) {
    if (subrange.type == SUBSTITUTION_LITERAL) {
      result.value().append(subrange.literal);
    } else {
      result.value().append(GetLinkerSubstitution(target, tool, subrange.type));
    }
  }
  return result;
}

// static
void SubstitutionWriter::ApplyListToLinkerAsOutputFile(
    const Target* target,
    const Tool* tool,
    const SubstitutionList& list,
    std::vector<OutputFile>* output) {
  for (const auto& item : list.list())
    output->push_back(ApplyPatternToLinkerAsOutputFile(target, tool, item));
}

// static
std::string SubstitutionWriter::GetLinkerSubstitution(const Target* target,
                                                      const Tool* tool,
                                                      SubstitutionType type) {
  // First try the common tool ones.
  std::string result;
  if (GetTargetSubstitution(target, type, &result))
    return result;

  // Fall-through to the linker-specific ones.
  switch (type) {
    case SUBSTITUTION_OUTPUT_DIR:
      // Use the target's value if there is one (it will have no expansion
      // patterns since it can directly use GN variables to compute whatever
      // path it wants), or the tool's default (which will contain further
      // expansions).
      if (target->output_dir().is_null()) {
        return ApplyPatternToLinkerAsOutputFile(target, tool,
                                                tool->default_output_dir())
            .value();
      }
      SetDirOrDotWithNoSlash(
          RebasePath(target->output_dir().value(),
                     target->settings()->build_settings()->build_dir()),
          &result);
      return result;

    case SUBSTITUTION_OUTPUT_EXTENSION:
      // Use the extension provided on the target if specified, otherwise
      // fall back on the default. Note that the target's output extension
      // does not include the dot but the tool's does.
      if (!target->output_extension_set())
        return tool->default_output_extension();
      if (target->output_extension().empty())
        return std::string();  // Explicitly set to no extension.
      return std::string(".") + target->output_extension();

    default:
      NOTREACHED();
      return std::string();
  }
}
