/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#ifndef cmLocalGenerator_h
#define cmLocalGenerator_h

#include "cmStandardIncludes.h"

class cmMakefile;
class cmGlobalGenerator;
class cmGeneratorTarget;
class cmTarget;
class cmTargetManifest;
class cmSourceFile;
class cmCustomCommand;

/** \class cmLocalGenerator
 * \brief Create required build files for a directory.
 *
 * Subclasses of this abstract class generate makefiles, DSP, etc for various
 * platforms. This class should never be constructed directly. A
 * GlobalGenerator will create it and invoke the appropriate commands on it.
 */
class cmLocalGenerator
{
public:
  cmLocalGenerator();
  virtual ~cmLocalGenerator();

  /**
   * Generate the makefile for this directory.
   */
  virtual void Generate() {}

  /**
   * Process the CMakeLists files for this directory to fill in the
   * Makefile ivar
   */
  virtual void Configure();

  /**
   * Calls TraceVSDependencies() on all targets of this generator.
   */
  virtual void TraceDependencies();

  virtual void AddHelperCommands() {}

  /**
   * Perform any final calculations prior to generation
   */
  virtual void ConfigureFinalPass();

  /**
   * Generate the install rules files in this directory.
   */
  virtual void GenerateInstallRules();

  /**
   * Generate the test files for tests.
   */
  virtual void GenerateTestFiles();

  /**
   * Generate a manifest of target files that will be built.
   */
  virtual void GenerateTargetManifest();

  ///! Get the makefile for this generator
  cmMakefile *GetMakefile() {
    return this->Makefile; };

  ///! Get the makefile for this generator, const version
    const cmMakefile *GetMakefile() const {
      return this->Makefile; };

  ///! Get the GlobalGenerator this is associated with
  cmGlobalGenerator *GetGlobalGenerator() {
    return this->GlobalGenerator; };
  const cmGlobalGenerator *GetGlobalGenerator() const {
    return this->GlobalGenerator; };

  ///! Set the Global Generator, done on creation by the GlobalGenerator
  void SetGlobalGenerator(cmGlobalGenerator *gg);

  /**
   * Convert something to something else. This is a centralized conversion
   * routine used by the generators to handle relative paths and the like.
   * The flags determine what is actually done.
   *
   * relative: treat the argument as a directory and convert it to make it
   * relative or full or unchanged. If relative (HOME, START etc) then that
   * specifies what it should be relative to.
   *
   * output: make the result suitable for output to a...
   *
   * optional: should any relative path operation be controlled by the rel
   * path setting
   */
  enum RelativeRoot { NONE, FULL, HOME, START, HOME_OUTPUT, START_OUTPUT };
  enum OutputFormat { UNCHANGED, MAKEFILE, SHELL, RESPONSE };
  std::string ConvertToOutputFormat(const char* source, OutputFormat output);
  std::string Convert(const char* remote, RelativeRoot local,
                      OutputFormat output = UNCHANGED,
                      bool optional = false);
  std::string Convert(RelativeRoot remote, const char* local,
                      OutputFormat output = UNCHANGED,
                      bool optional = false);

  /**
    * Get path for the specified relative root.
    */
  const char* GetRelativeRootPath(RelativeRoot relroot);

  /**
   * Convert the given path to an output path that is optionally
   * relative based on the cache option CMAKE_USE_RELATIVE_PATHS.  The
   * remote path must use forward slashes and not already be escaped
   * or quoted.
   */
  std::string ConvertToOptionallyRelativeOutputPath(const char* remote);

  ///! set/get the parent generator
  cmLocalGenerator* GetParent(){return this->Parent;}
  void SetParent(cmLocalGenerator* g) { this->Parent = g; g->AddChild(this); }

  ///! set/get the children
  void AddChild(cmLocalGenerator* g) { this->Children.push_back(g); }
  std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; };


  void AddArchitectureFlags(std::string& flags, cmGeneratorTarget* target,
                            const char *lang, const char* config);

  void AddLanguageFlags(std::string& flags, const char* lang,
                        const char* config);
  void AddCMP0018Flags(std::string &flags, cmTarget* target,
                       std::string const& lang);
  void AddConfigVariableFlags(std::string& flags, const char* var,
                              const char* config);
  ///! Append flags to a string.
  virtual void AppendFlags(std::string& flags, const char* newFlags);
  ///! Get the include flags for the current makefile and language
  std::string GetIncludeFlags(const std::vector<std::string> &includes,
                              const char* lang, bool forResponseFile = false);

  /**
   * Encode a list of preprocessor definitions for the compiler
   * command line.
   */
  void AppendDefines(std::set<std::string>& defines,
                     const char* defines_list);
  void AppendDefines(std::set<std::string>& defines,
                     std::string defines_list)
  {
    this->AppendDefines(defines, defines_list.c_str());
  }
  /**
   * Join a set of defines into a definesString with a space separator.
   */
  void JoinDefines(const std::set<std::string>& defines,
                   std::string &definesString,
                   const char* lang);

  /** Lookup and append options associated with a particular feature.  */
  void AppendFeatureOptions(std::string& flags, const char* lang,
                            const char* feature);

  /** \brief Get absolute path to dependency \a name
   *
   * Translate a dependency as given in CMake code to the name to
   * appear in a generated build file.
   * - If \a name is a utility target, returns false.
   * - If \a name is a CMake target, it will be transformed to the real output
   *   location of that target for the given configuration.
   * - If \a name is the full path to a file, it will be returned.
   * - Otherwise \a name is treated as a relative path with respect to
   *   the source directory of this generator.  This should only be
   *   used for dependencies of custom commands.
   */
  bool GetRealDependency(const char* name, const char* config,
                         std::string& dep);

  ///! for existing files convert to output path and short path if spaces
  std::string ConvertToOutputForExisting(const char* remote,
                                         RelativeRoot local = START_OUTPUT);

  /** For existing path identified by RelativeRoot convert to output
      path and short path if spaces.  */
  std::string ConvertToOutputForExisting(RelativeRoot remote,
                                         const char* local = 0);

  virtual std::string ConvertToIncludeReference(std::string const& path);

  /** Called from command-line hook to clear dependencies.  */
  virtual void ClearDependencies(cmMakefile* /* mf */,
                                 bool /* verbose */) {}

  /** Called from command-line hook to update dependencies.  */
  virtual bool UpdateDependencies(const char* /* tgtInfo */,
                                  bool /*verbose*/,
                                  bool /*color*/)
    { return true; }

  /** Get the include flags for the current makefile and language.  */
  void GetIncludeDirectories(std::vector<std::string>& dirs,
                             cmGeneratorTarget* target,
                             const char* lang = "C", const char *config = 0);

  /** Compute the language used to compile the given source file.  */
  const char* GetSourceFileLanguage(const cmSourceFile& source);

  // Fill the vector with the target names for the object files,
  // preprocessed files and assembly files.
  virtual void GetIndividualFileTargets(std::vector<std::string>&) {}

  // Create a struct to hold the varibles passed into
  // ExpandRuleVariables
  struct RuleVariables
  {
    RuleVariables()
      {
        memset(this, 0,  sizeof(*this));
      }
    cmTarget* CMTarget;
    const char* TargetPDB;
    const char* TargetVersionMajor;
    const char* TargetVersionMinor;
    const char* Language;
    const char* Objects;
    const char* Target;
    const char* LinkLibraries;
    const char* Source;
    const char* AssemblySource;
    const char* PreprocessedSource;
    const char* Output;
    const char* Object;
    const char* ObjectDir;
    const char* Flags;
    const char* ObjectsQuoted;
    const char* SONameFlag;
    const char* TargetSOName;
    const char* TargetInstallNameDir;
    const char* LinkFlags;
    const char* LanguageCompileFlags;
    const char* Defines;
    const char* RuleLauncher;
    const char* DependencyFile;
  };

  /** Set whether to treat conversions to SHELL as a link script shell.  */
  void SetLinkScriptShell(bool b) { this->LinkScriptShell = b; }

  /** Escape the given string to be used as a command line argument in
      the native build system shell.  Optionally allow the build
      system to replace make variable references.  Optionally adjust
      escapes for the special case of passing to the native echo
      command.  */
  std::string EscapeForShell(const char* str, bool makeVars = false,
                             bool forEcho = false);

  /** Backwards-compatibility version of EscapeForShell.  */
  std::string EscapeForShellOldStyle(const char* str);

  /** Escape the given string as an argument in a CMake script.  */
  static std::string EscapeForCMake(const char* str);

  enum FortranFormat
    {
    FortranFormatNone,
    FortranFormatFixed,
    FortranFormatFree
    };
  FortranFormat GetFortranFormat(const char* value);

  /**
   * Convert the given remote path to a relative path with respect to
   * the given local path.  The local path must be given in component
   * form (see SystemTools::SplitPath) without a trailing slash.  The
   * remote path must use forward slashes and not already be escaped
   * or quoted.
   */
  std::string ConvertToRelativePath(const std::vector<std::string>& local,
                                    const char* remote, bool force=false);

  /**
   * Get the relative path from the generator output directory to a
   * per-target support directory.
   */
  virtual std::string GetTargetDirectory(cmTarget const& target) const;

  /**
   * Get the level of backwards compatibility requested by the project
   * in this directory.  This is the value of the CMake variable
   * CMAKE_BACKWARDS_COMPATIBILITY whose format is
   * "major.minor[.patch]".  The returned integer is encoded as
   *
   *   CMake_VERSION_ENCODE(major, minor, patch)
   *
   * and is monotonically increasing with the CMake version.
   */
  unsigned int GetBackwardsCompatibility();

  /**
   * Test whether compatibility is set to a given version or lower.
   */
  bool NeedBackwardsCompatibility(unsigned int major,
                                  unsigned int minor,
                                  unsigned int patch = 0xFFu);

  /**
   * Generate a Mac OS X application bundle Info.plist file.
   */
  void GenerateAppleInfoPList(cmTarget* target, const char* targetName,
                              const char* fname);

  /**
   * Generate a Mac OS X framework Info.plist file.
   */
  void GenerateFrameworkInfoPList(cmTarget* target,
                                  const char* targetName,
                                  const char* fname);
  /** Construct a comment for a custom command.  */
  std::string ConstructComment(const cmCustomCommand& cc,
                               const char* default_comment = "");
  // Compute object file names.
  std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
                                             std::string const& dir_max,
                                             bool* hasSourceExtension = 0);

  /** Fill out these strings for the given target.  Libraries to link,
   *  flags, and linkflags. */
  void GetTargetFlags(std::string& linkLibs,
                      std::string& flags,
                      std::string& linkFlags,
                      std::string& frameworkPath,
                      std::string& linkPath,
                      cmGeneratorTarget* target);

protected:
  ///! put all the libraries for a target on into the given stream
  virtual void OutputLinkLibraries(std::string& linkLibraries,
                                   std::string& frameworkPath,
                                   std::string& linkPath,
                                   cmGeneratorTarget &,
                                   bool relink);

  // Expand rule variables in CMake of the type found in language rules
  void ExpandRuleVariables(std::string& string,
                           const RuleVariables& replaceValues);
  // Expand rule variables in a single string
  std::string ExpandRuleVariable(std::string const& variable,
                                 const RuleVariables& replaceValues);

  const char* GetRuleLauncher(cmTarget* target, const char* prop);
  void InsertRuleLauncher(std::string& s, cmTarget* target,
                          const char* prop);


  /** Convert a target to a utility target for unsupported
   *  languages of a generator */
  void AddBuildTargetRule(const char* llang, cmGeneratorTarget& target);
  ///! add a custom command to build a .o file that is part of a target
  void AddCustomCommandToCreateObject(const char* ofname,
                                      const char* lang,
                                      cmSourceFile& source,
                                      cmGeneratorTarget& target);
  // Create Custom Targets and commands for unsupported languages
  // The set passed in should contain the languages supported by the
  // generator directly.  Any targets containing files that are not
  // of the types listed will be compiled as custom commands and added
  // to a custom target.
  void CreateCustomTargetsAndCommands(std::set<cmStdString> const&);

  // Handle old-style install rules stored in the targets.
  void GenerateTargetInstallRules(
    std::ostream& os, const char* config,
    std::vector<std::string> const& configurationTypes);

  std::string& CreateSafeUniqueObjectFileName(const char* sin,
                                              std::string const& dir_max);
  void ComputeObjectMaxPath();

  void ConfigureRelativePaths();
  std::string FindRelativePathTopSource();
  std::string FindRelativePathTopBinary();
  void SetupPathConversions();

  virtual std::string ConvertToLinkReference(std::string const& lib);

  /** Check whether the native build system supports the given
      definition.  Issues a warning.  */
  virtual bool CheckDefinition(std::string const& define) const;

  /** Read the input CMakeLists.txt file.  */
  void ReadInputFile();

  cmMakefile *Makefile;
  cmGlobalGenerator *GlobalGenerator;
  // members used for relative path function ConvertToMakefilePath
  std::string RelativePathToSourceDir;
  std::string RelativePathToBinaryDir;
  std::vector<std::string> HomeDirectoryComponents;
  std::vector<std::string> StartDirectoryComponents;
  std::vector<std::string> HomeOutputDirectoryComponents;
  std::vector<std::string> StartOutputDirectoryComponents;
  cmLocalGenerator* Parent;
  std::vector<cmLocalGenerator*> Children;
  std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
  std::string::size_type ObjectPathMax;
  std::set<cmStdString> ObjectMaxPathViolations;
  bool WindowsShell;
  bool WindowsVSIDE;
  bool WatcomWMake;
  bool MinGWMake;
  bool NMake;
  bool ForceUnixPath;
  bool MSYSShell;
  bool LinkScriptShell;
  bool UseRelativePaths;
  bool IgnoreLibPrefix;
  bool Configured;
  bool EmitUniversalBinaryFlags;
  // A type flag is not nice. It's used only in TraceDependencies().
  bool IsMakefileGenerator;
  // Hack for ExpandRuleVariable until object-oriented version is
  // committed.
  std::string TargetImplib;

  // The top-most directories for relative path conversion.  Both the
  // source and destination location of a relative path conversion
  // must be underneath one of these directories (both under source or
  // both under binary) in order for the relative path to be evaluated
  // safely by the build tools.
  std::string RelativePathTopSource;
  std::string RelativePathTopBinary;
  bool RelativePathsConfigured;
  bool PathConversionsSetup;

  unsigned int BackwardsCompatibility;
  bool BackwardsCompatibilityFinal;
private:
  std::string ConvertToOutputForExistingCommon(const char* remote,
                                               std::string const& result);

  void AddSharedFlags(std::string& flags, const char* lang, bool shared);
  bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
  void AddPositionIndependentFlags(std::string& flags, std::string const& l,
                                   int targetType);
};

#endif
