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

#ifndef TOOLS_GN_FILE_TEMPLATE_H_
#define TOOLS_GN_FILE_TEMPLATE_H_

#include <iosfwd>

#include "base/basictypes.h"
#include "base/containers/stack_container.h"
#include "tools/gn/err.h"
#include "tools/gn/value.h"

struct EscapeOptions;
class ParseNode;
class Settings;
class SourceFile;
class Target;

extern const char kSourceExpansion_Help[];

// A FileTemplate object implements source expansion for a given "template"
// (either outputs or args, depending on the target type).
//
// There are two ways you can use this. You can make a template and then
// apply a source to it to get a list of outputs manually. Or you can do the
// actual substitution in Ninja, writing the arguments in a rule and using
// variables in build statements to invoke the rule with the right
// substitutions.
class FileTemplate {
 public:
  struct Subrange {
    // See the help in the .cc file for what these mean.
    enum Type {
      LITERAL = 0,

      SOURCE,  // {{source}}
      NAME_PART,  // {{source_name_part}}
      FILE_PART,  // {{source_file_part}}
      SOURCE_DIR,  // {{source_dir}}
      ROOT_RELATIVE_DIR,  // {{root_relative_dir}}
      SOURCE_GEN_DIR,  // {{source_gen_dir}}
      SOURCE_OUT_DIR,  // {{source_out_dir}}

      NUM_TYPES  // Must be last
    };
    Subrange(Type t, const std::string& l = std::string())
        : type(t),
          literal(l) {
    }

    Type type;

    // When type_ == LITERAL, this specifies the literal.
    std::string literal;
  };

  // Constructs a template from the given value. On error, the err will be
  // set. In this case you should not use this object.
  FileTemplate(const Settings* settings, const Value& t, Err* err);
  FileTemplate(const Settings* settings, const std::vector<std::string>& t);
  FileTemplate(const Settings* settings, const std::vector<SourceFile>& t);

  ~FileTemplate();

  // Returns an output template representing the given target's script
  // outputs.
  static FileTemplate GetForTargetOutputs(const Target* target);

  // Returns true if the given substitution type is used by this template.
  bool IsTypeUsed(Subrange::Type type) const;

  // Returns true if there are any substitutions.
  bool has_substitutions() const { return has_substitutions_; }

  // Applies the template to one source file. The results will be *appended* to
  // the output.
  void Apply(const SourceFile& source,
             std::vector<std::string>* output) const;

  // Writes a string representing the template with Ninja variables for the
  // substitutions, and the literals escaped for Ninja consumption.
  //
  // For example, if the input is "foo{{source_name_part}}bar" this will write
  // foo${source_name_part}bar. If there are multiple templates (we were
  // constucted with a list of more than one item) then the values will be
  // separated by spaces.
  //
  // If this template is nonempty, we will first print out a space to separate
  // it from the previous command.
  //
  // The names used for the Ninja variables will be the same ones used by
  // WriteNinjaVariablesForSubstitution. You would use this to define the Ninja
  // rule, and then define the variables to substitute for each file using
  // WriteNinjaVariablesForSubstitution.
  void WriteWithNinjaExpansions(std::ostream& out) const;

  // Writes to the given stream the variable declarations for extracting the
  // required parts of the given source file string. The results will be
  // indented two spaces.
  //
  // This is used to set up a build statement to invoke a rule where the rule
  // contains a representation of this file template to be expanded by Ninja
  // (see GetWithNinjaExpansions).
  void WriteNinjaVariablesForSubstitution(
      std::ostream& out,
      const Settings* settings,
      const SourceFile& source,
      const EscapeOptions& escape_options) const;

  // Returns the Ninja variable name used by the above Ninja functions to
  // substitute for the given type.
  static const char* GetNinjaVariableNameForType(Subrange::Type type);

  // Extracts the given type of substitution from the given source. The source
  // should be the file name relative to the output directory.
  static std::string GetSubstitution(const Settings* settings,
                                     const SourceFile& source,
                                     Subrange::Type type);

  // Known template types, these include the "{{ }}"
  static const char kSource[];
  static const char kSourceNamePart[];
  static const char kSourceFilePart[];
  static const char kSourceDir[];
  static const char kRootRelDir[];
  static const char kSourceGenDir[];
  static const char kSourceOutDir[];

 private:
  typedef base::StackVector<Subrange, 8> Template;
  typedef base::StackVector<Template, 8> TemplateVector;

  void ParseInput(const Value& value, Err* err);

  // Parses a template string and adds it to the templates_ list.
  void ParseOneTemplateString(const std::string& str);

  const Settings* settings_;

  TemplateVector templates_;

  // The corresponding value is set to true if the given subrange type is
  // required. This allows us to precompute these types whem applying them
  // to a given source file.
  bool types_required_[Subrange::NUM_TYPES];

  // Set when any of the types_required_ is true. Otherwise, everythins is a
  // literal (a common case so we can optimize some code paths).
  bool has_substitutions_;
};

#endif  // TOOLS_GN_FILE_TEMPLATE_H_
