// 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 "tools/gn/file_template.h"

#include <algorithm>
#include <iostream>

#include "tools/gn/escape.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/string_utils.h"
#include "tools/gn/target.h"

const char FileTemplate::kSource[] = "{{source}}";
const char FileTemplate::kSourceNamePart[] = "{{source_name_part}}";
const char FileTemplate::kSourceFilePart[] = "{{source_file_part}}";
const char FileTemplate::kSourceDir[] = "{{source_dir}}";
const char FileTemplate::kRootRelDir[] = "{{source_root_relative_dir}}";
const char FileTemplate::kSourceGenDir[] = "{{source_gen_dir}}";
const char FileTemplate::kSourceOutDir[] = "{{source_out_dir}}";

const char kSourceExpansion_Help[] =
    "How Source Expansion Works\n"
    "\n"
    "  Source expansion is used for the action_foreach and copy target types\n"
    "  to map source file names to output file names or arguments.\n"
    "\n"
    "  To perform source expansion in the outputs, GN maps every entry in the\n"
    "  sources to every entry in the outputs list, producing the cross\n"
    "  product of all combinations, expanding placeholders (see below).\n"
    "\n"
    "  Source expansion in the args works similarly, but performing the\n"
    "  placeholder substitution produces a different set of arguments for\n"
    "  each invocation of the script.\n"
    "\n"
    "  If no placeholders are found, the outputs or args list will be treated\n"
    "  as a static list of literal file names that do not depend on the\n"
    "  sources.\n"
    "\n"
    "  See \"gn help copy\" and \"gn help action_foreach\" for more on how\n"
    "  this is applied.\n"
    "\n"
    "Placeholders\n"
    "\n"
    "  {{source}}\n"
    "      The name of the source file relative to the root build output\n"
    "      directory (which is the current directory when running compilers\n"
    "      and scripts). This will generally be used for specifying inputs\n"
    "      to a script in the \"args\" variable.\n"
    "        \"//foo/bar/baz.txt\" => \"../../foo/bar/baz.txt\"\n"
    "\n"
    "  {{source_file_part}}\n"
    "      The file part of the source including the extension.\n"
    "        \"//foo/bar/baz.txt\" => \"baz.txt\"\n"
    "\n"
    "  {{source_name_part}}\n"
    "      The filename part of the source file with no directory or\n"
    "      extension. This will generally be used for specifying a\n"
    "      transformation from a soruce file to a destination file with the\n"
    "      same name but different extension.\n"
    "        \"//foo/bar/baz.txt\" => \"baz\"\n"
    "\n"
    "  {{source_dir}}\n"
    "      The directory containing the source file, relative to the build\n"
    "      directory, with no trailing slash.\n"
    "        \"//foo/bar/baz.txt\" => \"../../foo/bar\"\n"
    "\n"
    "  {{source_root_relative_dir}}\n"
    "      The path to the source file's directory relative to the source\n"
    "      root, with no leading \"//\" or trailing slashes. If the path is\n"
    "      system-absolute, (beginning in a single slash) this will just\n"
    "      return the path with no trailing slash.\n"
    "        \"//foo/bar/baz.txt\" => \"foo/bar\"\n"
    "\n"
    "  {{source_gen_dir}}\n"
    "      The generated file directory corresponding to the source file's\n"
    "      path, relative to the build directory. This will be different than\n"
    "      the target's generated file directory if the source file is in a\n"
    "      different directory than the build.gn file. If the input path is\n"
    "      system absolute, this will return the root generated file\n"
    "      directory."
    "        \"//foo/bar/baz.txt\" => \"gen/foo/bar\"\n"
    "\n"
    "  {{source_out_dir}}\n"
    "      The object file directory corresponding to the source file's\n"
    "      path, relative to the build directory. this us be different than\n"
    "      the target's out directory if the source file is in a different\n"
    "      directory than the build.gn file. if the input path is system\n"
    "      absolute, this will return the root generated file directory.\n"
    "        \"//foo/bar/baz.txt\" => \"obj/foo/bar\"\n"
    "\n"
    "Examples\n"
    "\n"
    "  Non-varying outputs:\n"
    "    action(\"hardcoded_outputs\") {\n"
    "      sources = [ \"input1.idl\", \"input2.idl\" ]\n"
    "      outputs = [ \"$target_out_dir/output1.dat\",\n"
    "                  \"$target_out_dir/output2.dat\" ]\n"
    "    }\n"
    "  The outputs in this case will be the two literal files given.\n"
    "\n"
    "  Varying outputs:\n"
    "    action_foreach(\"varying_outputs\") {\n"
    "      sources = [ \"input1.idl\", \"input2.idl\" ]\n"
    "      outputs = [ \"$target_out_dir/{{source_name_part}}.h\",\n"
    "                  \"$target_out_dir/{{source_name_part}}.cc\" ]\n"
    "    }\n"
    "  Performing source expansion will result in the following output names:\n"
    "    //out/Debug/obj/mydirectory/input1.h\n"
    "    //out/Debug/obj/mydirectory/input1.cc\n"
    "    //out/Debug/obj/mydirectory/input2.h\n"
    "    //out/Debug/obj/mydirectory/input2.cc\n";

FileTemplate::FileTemplate(const Settings* settings, const Value& t, Err* err)
    : settings_(settings),
      has_substitutions_(false) {
  std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
  ParseInput(t, err);
}

FileTemplate::FileTemplate(const Settings* settings,
                           const std::vector<std::string>& t)
    : settings_(settings),
      has_substitutions_(false) {
  std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
  for (size_t i = 0; i < t.size(); i++)
    ParseOneTemplateString(t[i]);
}

FileTemplate::FileTemplate(const Settings* settings,
                           const std::vector<SourceFile>& t)
    : settings_(settings),
      has_substitutions_(false) {
  std::fill(types_required_, &types_required_[Subrange::NUM_TYPES], false);
  for (size_t i = 0; i < t.size(); i++)
    ParseOneTemplateString(t[i].value());
}

FileTemplate::~FileTemplate() {
}

// static
FileTemplate FileTemplate::GetForTargetOutputs(const Target* target) {
  const Target::FileList& outputs = target->action_values().outputs();
  std::vector<std::string> output_template_args;
  for (size_t i = 0; i < outputs.size(); i++)
    output_template_args.push_back(outputs[i].value());
  return FileTemplate(target->settings(), output_template_args);
}

bool FileTemplate::IsTypeUsed(Subrange::Type type) const {
  DCHECK(type > Subrange::LITERAL && type < Subrange::NUM_TYPES);
  return types_required_[type];
}

void FileTemplate::Apply(const SourceFile& source,
                         std::vector<std::string>* output) const {
  // Compute all substitutions needed so we can just do substitutions below.
  // We skip the LITERAL one since that varies each time.
  std::string subst[Subrange::NUM_TYPES];
  for (int i = 1; i < Subrange::NUM_TYPES; i++) {
    if (types_required_[i]) {
      subst[i] =
          GetSubstitution(settings_, source, static_cast<Subrange::Type>(i));
    }
  }

  size_t first_output_index = output->size();
  output->resize(output->size() + templates_.container().size());
  for (size_t template_i = 0;
       template_i < templates_.container().size(); template_i++) {
    const Template& t = templates_[template_i];
    std::string& cur_output = (*output)[first_output_index + template_i];
    for (size_t subrange_i = 0; subrange_i < t.container().size();
         subrange_i++) {
      if (t[subrange_i].type == Subrange::LITERAL)
        cur_output.append(t[subrange_i].literal);
      else
        cur_output.append(subst[t[subrange_i].type]);
    }
  }
}

void FileTemplate::WriteWithNinjaExpansions(std::ostream& out) const {
  EscapeOptions escape_options;
  escape_options.mode = ESCAPE_NINJA_COMMAND;
  escape_options.inhibit_quoting = true;

  for (size_t template_i = 0;
       template_i < templates_.container().size(); template_i++) {
    out << " ";  // Separate args with spaces.

    const Template& t = templates_[template_i];

    // Escape each subrange into a string. Since we're writing out Ninja
    // variables, we can't quote the whole thing, so we write in pieces, only
    // escaping the literals, and then quoting the whole thing at the end if
    // necessary.
    bool needs_quoting = false;
    std::string item_str;
    for (size_t subrange_i = 0; subrange_i < t.container().size();
         subrange_i++) {
      if (t[subrange_i].type == Subrange::LITERAL) {
        bool cur_needs_quoting = false;
        item_str.append(EscapeString(t[subrange_i].literal, escape_options,
                                     &cur_needs_quoting));
        needs_quoting |= cur_needs_quoting;
      } else {
        // Don't escape this since we need to preserve the $.
        item_str.append("${");
        item_str.append(GetNinjaVariableNameForType(t[subrange_i].type));
        item_str.append("}");
      }
    }

    if (needs_quoting || item_str.empty()) {
      // Need to shell quote the whole string. We also need to quote empty
      // strings or it would be impossible to pass "" as a command-line
      // argument.
      out << '"' << item_str << '"';
    } else {
      out << item_str;
    }
  }
}

void FileTemplate::WriteNinjaVariablesForSubstitution(
    std::ostream& out,
    const Settings* settings,
    const SourceFile& source,
    const EscapeOptions& escape_options) const {
  for (int i = 1; i < Subrange::NUM_TYPES; i++) {
    if (types_required_[i]) {
      Subrange::Type type = static_cast<Subrange::Type>(i);
      out << "  " << GetNinjaVariableNameForType(type) << " = ";
      EscapeStringToStream(out, GetSubstitution(settings, source, type),
                           escape_options);
      out << std::endl;
    }
  }
}

// static
const char* FileTemplate::GetNinjaVariableNameForType(Subrange::Type type) {
  switch (type) {
    case Subrange::SOURCE:
      return "source";
    case Subrange::NAME_PART:
      return "source_name_part";
    case Subrange::FILE_PART:
      return "source_file_part";
    case Subrange::SOURCE_DIR:
      return "source_dir";
    case Subrange::ROOT_RELATIVE_DIR:
      return "source_root_rel_dir";
    case Subrange::SOURCE_GEN_DIR:
      return "source_gen_dir";
    case Subrange::SOURCE_OUT_DIR:
      return "source_out_dir";

    default:
      NOTREACHED();
  }
  return "";
}

// static
std::string FileTemplate::GetSubstitution(const Settings* settings,
                                          const SourceFile& source,
                                          Subrange::Type type) {
  switch (type) {
    case Subrange::SOURCE:
      if (source.is_system_absolute())
        return source.value();
      return RebaseSourceAbsolutePath(source.value(),
                                      settings->build_settings()->build_dir());

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

    case Subrange::FILE_PART:
      return source.GetName();

    case Subrange::SOURCE_DIR:
      if (source.is_system_absolute())
        return DirectoryWithNoLastSlash(source.GetDir());
      return RebaseSourceAbsolutePath(
          DirectoryWithNoLastSlash(source.GetDir()),
          settings->build_settings()->build_dir());

    case Subrange::ROOT_RELATIVE_DIR:
      if (source.is_system_absolute())
        return DirectoryWithNoLastSlash(source.GetDir());
      return RebaseSourceAbsolutePath(
          DirectoryWithNoLastSlash(source.GetDir()), SourceDir("//"));

    case Subrange::SOURCE_GEN_DIR:
      return RebaseSourceAbsolutePath(
          DirectoryWithNoLastSlash(
              GetGenDirForSourceDir(settings, source.GetDir())),
          settings->build_settings()->build_dir());

    case Subrange::SOURCE_OUT_DIR:
      return RebaseSourceAbsolutePath(
          DirectoryWithNoLastSlash(
              GetOutputDirForSourceDir(settings, source.GetDir())),
          settings->build_settings()->build_dir());

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

void FileTemplate::ParseInput(const Value& value, Err* err) {
  switch (value.type()) {
    case Value::STRING:
      ParseOneTemplateString(value.string_value());
      break;
    case Value::LIST:
      for (size_t i = 0; i < value.list_value().size(); i++) {
        if (!value.list_value()[i].VerifyTypeIs(Value::STRING, err))
          return;
        ParseOneTemplateString(value.list_value()[i].string_value());
      }
      break;
    default:
      *err = Err(value, "File template must be a string or list.",
                 "A sarcastic comment about your skills goes here.");
  }
}

void FileTemplate::ParseOneTemplateString(const std::string& str) {
  templates_.container().resize(templates_.container().size() + 1);
  Template& t = templates_[templates_.container().size() - 1];

  size_t cur = 0;
  while (true) {
    size_t next = str.find("{{", cur);

    // Pick up everything from the previous spot to here as a literal.
    if (next == std::string::npos) {
      if (cur != str.size())
        t.container().push_back(Subrange(Subrange::LITERAL, str.substr(cur)));
      break;
    } else if (next > cur) {
      t.container().push_back(
          Subrange(Subrange::LITERAL, str.substr(cur, next - cur)));
    }

    // Given the name of the string constant and enum for a template parameter,
    // checks for it and stores it. Writing this as a function requires passing
    // the entire state of this function as arguments, so this actually ends
    // up being more clear.
    #define IF_MATCH_THEN_STORE(const_name, enum_name) \
        if (str.compare(next, arraysize(const_name) - 1, const_name) == 0) { \
          t.container().push_back(Subrange(Subrange::enum_name)); \
          types_required_[Subrange::enum_name] = true; \
          has_substitutions_ = true; \
          cur = next + arraysize(const_name) - 1; \
        }

    // Decode the template param.
    IF_MATCH_THEN_STORE(kSource, SOURCE)
    else IF_MATCH_THEN_STORE(kSourceNamePart, NAME_PART)
    else IF_MATCH_THEN_STORE(kSourceFilePart, FILE_PART)
    else IF_MATCH_THEN_STORE(kSourceDir, SOURCE_DIR)
    else IF_MATCH_THEN_STORE(kRootRelDir, ROOT_RELATIVE_DIR)
    else IF_MATCH_THEN_STORE(kSourceGenDir, SOURCE_GEN_DIR)
    else IF_MATCH_THEN_STORE(kSourceOutDir, SOURCE_OUT_DIR)
    else {
      // If it's not a match, treat it like a one-char literal (this will be
      // rare, so it's not worth the bother to add to the previous literal) so
      // we can keep going.
      t.container().push_back(Subrange(Subrange::LITERAL, "{"));
      cur = next + 1;
    }

    #undef IF_MATCH_THEN_STORE
  }
}
