// 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 "base/stl_util.h"
#include "tools/gn/functions.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/scope.h"
#include "tools/gn/settings.h"
#include "tools/gn/substitution_list.h"
#include "tools/gn/substitution_writer.h"
#include "tools/gn/target.h"
#include "tools/gn/value_extractors.h"

namespace functions {

const char kProcessFileTemplate[] = "process_file_template";
const char kProcessFileTemplate_HelpShort[] =
    "process_file_template: Do template expansion over a list of files.";
const char kProcessFileTemplate_Help[] =
    R"(process_file_template: Do template expansion over a list of files.

  process_file_template(source_list, template)

  process_file_template applies a template list to a source file list,
  returning the result of applying each template to each source. This is
  typically used for computing output file names from input files.

  In most cases, get_target_outputs() will give the same result with shorter,
  more maintainable code. This function should only be used when that function
  can't be used (like there's no target or the target is defined in another
  build file).

Arguments

  The source_list is a list of file names.

  The template can be a string or a list. If it is a list, multiple output
  strings are generated for each input.

  The template should contain source expansions to which each name in the
  source list is applied. See "gn help source_expansion".

Example

  sources = [
    "foo.idl",
    "bar.idl",
  ]
  myoutputs = process_file_template(
      sources,
      [ "$target_gen_dir/{{source_name_part}}.cc",
        "$target_gen_dir/{{source_name_part}}.h" ])

 The result in this case will be:
    [ "//out/Debug/foo.cc"
      "//out/Debug/foo.h"
      "//out/Debug/bar.cc"
      "//out/Debug/bar.h" ]
)";

Value RunProcessFileTemplate(Scope* scope,
                             const FunctionCallNode* function,
                             const std::vector<Value>& args,
                             Err* err) {
  if (args.size() != 2) {
    *err = Err(function->function(), "Expected two arguments");
    return Value();
  }

  // Source list.
  Target::FileList input_files;
  if (!ExtractListOfRelativeFiles(scope->settings()->build_settings(), args[0],
                                  scope->GetSourceDir(), &input_files, err))
    return Value();

  std::vector<std::string> result_files;
  SubstitutionList subst;

  // Template.
  const Value& template_arg = args[1];
  if (template_arg.type() == Value::STRING) {
    // Convert the string to a SubstitutionList with one pattern in it to
    // simplify the code below.
    std::vector<std::string> list;
    list.push_back(template_arg.string_value());
    if (!subst.Parse(list, template_arg.origin(), err))
      return Value();
  } else if (template_arg.type() == Value::LIST) {
    if (!subst.Parse(template_arg, err))
      return Value();
  } else {
    *err = Err(template_arg, "Not a string or a list.");
    return Value();
  }

  auto& types = subst.required_types();
  if (base::ContainsValue(types, &SubstitutionSourceTargetRelative)) {
    *err = Err(template_arg, "Not a valid substitution type for the function.");
    return Value();
  }

  SubstitutionWriter::ApplyListToSourcesAsString(
      nullptr, scope->settings(), subst, input_files, &result_files);

  // Convert the list of strings to the return Value.
  Value ret(function, Value::LIST);
  ret.list_value().reserve(result_files.size());
  for (const auto& file : result_files)
    ret.list_value().push_back(Value(function, file));

  return ret;
}

}  // namespace functions
