#ifndef __TQPathManager__
#define __TQPathManager__

#include <iostream>
#include <map>
#include <string>
#include "TString.h"

class TQPathManager{
public:

  ///////////////////// static methods /////////////////////


 
  // Like findFileFromList(...). Instead of a string of paths, it takes an
  // environment variable as input and searches the paths therein.
  static std::string findFileFromEnvVar(const TString& filename, const std::string& envVar, bool printWarnings = true);

  // This method does not return results relative to the execution directory.
  static std::string findFileFromEnvVarWithoutExecDir(const TString& filename, const std::string& envVar, bool printWarnings = true);

  // Searches a list of paths (variable searchPath, different paths separated
  // by ":") for filename. When the first file has been found, stop and return
  // its absolute path.
  static std::string findFileFromList(TString filename, const std::string& searchPathList, bool printWarnings = true);

  // This method does not return results relative to the execution directory.
  static std::string findFileFromListWithoutExecDir(TString filename, const std::string& searchPathList, bool printWarnings = true);

  // Returns gPathManager. This instance is automatically created and supposed
  // to be used to handle paths. Don't create your own instance.
  static TQPathManager* getPathManager();

private:
  
  // internal implementation of findFileFromEnvVar
  static std::string findFileFromEnvVar_internal(const TString& filename, const std::string& envVar, bool printWarnings, bool searchExecutionDir);

  // internal implementation of findFileFromList
  static std::string findFileFromList_internal(TString filename, const std::string& searchPathList, bool printWarnings, bool searchExecutionDir);
  
  // auxilliary variable to store result of reading the CAFUSELOCALSTORAGE 
  // env var while loading the library
  static const bool gUseTemporaryStorageDefault;
  
  //////////////////////////////////////////////////////////

public:
  bool getUseTemporaryStorage() const;
  void setUseTemporaryStorage(bool useTemporaryStorage);
  TString getLocalDirectory() const;
  bool setLocalDirectory(TString localDirectory);
  void setVerbose(bool verbose);
  void setWorkingDirectory(TString dir);

  // If you have retrieved a local path before, this method will tell the path
  // manager that it exists. As long as the file is registered, the path manager
  // will always return the local path and never the target path.
  // Note that the argument is not a local path, but the targetFile (the same
  // argument that you used to call getLocalPath(...) in the first place).
  void registerLocalPath(TString targetFile);
  void unregisterLocalPath(TString targetFile);

  // Returns the full path of the target filename (i.e. path where output will
  // be saved for user).
  std::string getTargetPath(TString filename, bool printWarnings=true);

  // Returns the full path of a local file. If something is written to this
  // local file, copy it to the target location in the destructor.
  std::string getLocalPath(TString filename);

  // Find the config file "filename"
  std::string findConfigPath(TString filename, bool errorMessageIfNotFound = true, bool searchExecutionDir = true);

  // Deletes the local file that corresponds to the target file given as
  // argument and returns true. Returns false if the target file has never been
  // used to create a local file.
  bool deleteLocalFile(TString filename);

  // Returns vector of all target paths of files (local and target) that have
  // been requested and not deleted. This might contain requested files that
  // were never written by the user.
  std::vector<TString> getAllTargetPaths();

  // Constructor: Show a warning if environment variable CAFOUTPUTDIR cannot
  // be read.
  // gUseTemporaryStrageDefault is read from env vars "CAFUSETEMPDIR" or 
  // (at lower priority) "CAFUSELOCALSTORAGE" upon loading the library
  TQPathManager(bool useTemporaryStorage = gUseTemporaryStorageDefault);
  TQPathManager(TString localDirectory, bool useTemporaryStorage = gUseTemporaryStorageDefault);

  // Destructor: Copy all local files to target location.
  virtual ~TQPathManager();

  ClassDef(TQPathManager, 0);

private:
  
  
  // Counter to give local files a unique name.
  static int filenameIndex;

  // Pointer to instance of TQPathManager that is used throughout the entire
  // analysis. Don't create another instance.
  static TQPathManager gPathManager;
  static bool gPathManagerExists;

  // This vector has the names of all target paths that have been returned by
  // getTargetPath.
  std::vector<TString> targetPaths;

  // Holds name of working directory. Is only set once at the beginning. Used
  // as default for output if $CAFOUTPUTDIR is not specified.
  TString pwd;

  // This map holds the link between target files (relative to environment
  // variable CAFOUTPUTDIR) and local paths (absolute path).
  // < targetFile, localPath >
  std::map<TString, TString> localPaths;

  // This map works in parallel to localPaths. If getTargetPath() is called,
  // targetFile is in the map and the bool is true, then the local path is
  // returned. This behavior can be requested with alwaysReturnLocalPathFor().
  std::map<TString, bool> alwaysReturnLocalPath;

  // Local files are written in this directory.
  TString localDirectory;

  // difference to getTargetPath(...): does not store file path in targetPaths
  TString getTargetPathName(TString targetFile) const;

  // Reads $CAFOUTPUTDIR and decides if it's good to use. If not, it returns
  // $PWD.
  TString determineTargetDir() const;

  // Returns true if the filename is in localPaths among target files
  bool isInLocalPaths_target(TString filename) const;

  // Returns true if the filePath is in localPaths among local paths.
  bool isInLocalPaths_local(const TString& filePath) const;

  // Returns true if the filePath is in targetPaths.
  bool isInTargetPaths(const TString& filePath) const;

  // Erases this entry from targetPaths.
  void deleteTargetPathEntry(const TString& filePath);

  // Called by constructors.
  void initialize(const TString& localDirectory, bool useTemporaryStorage);

  // Use the feature of temporary storage. If false, getLocalPath(...) has the
  // same functionality as getTargetPath(...).
  bool useTemporaryStorage;

  // Indicates if paths have been requested (false in constructor, true after
  // after getLocalPath or getTargetPath are called).
  bool pathsRequested;

  // Write verbose output
  bool verbose;
};

#endif
 TQPathManager.h:1
 TQPathManager.h:2
 TQPathManager.h:3
 TQPathManager.h:4
 TQPathManager.h:5
 TQPathManager.h:6
 TQPathManager.h:7
 TQPathManager.h:8
 TQPathManager.h:9
 TQPathManager.h:10
 TQPathManager.h:11
 TQPathManager.h:12
 TQPathManager.h:13
 TQPathManager.h:14
 TQPathManager.h:15
 TQPathManager.h:16
 TQPathManager.h:17
 TQPathManager.h:18
 TQPathManager.h:19
 TQPathManager.h:20
 TQPathManager.h:21
 TQPathManager.h:22
 TQPathManager.h:23
 TQPathManager.h:24
 TQPathManager.h:25
 TQPathManager.h:26
 TQPathManager.h:27
 TQPathManager.h:28
 TQPathManager.h:29
 TQPathManager.h:30
 TQPathManager.h:31
 TQPathManager.h:32
 TQPathManager.h:33
 TQPathManager.h:34
 TQPathManager.h:35
 TQPathManager.h:36
 TQPathManager.h:37
 TQPathManager.h:38
 TQPathManager.h:39
 TQPathManager.h:40
 TQPathManager.h:41
 TQPathManager.h:42
 TQPathManager.h:43
 TQPathManager.h:44
 TQPathManager.h:45
 TQPathManager.h:46
 TQPathManager.h:47
 TQPathManager.h:48
 TQPathManager.h:49
 TQPathManager.h:50
 TQPathManager.h:51
 TQPathManager.h:52
 TQPathManager.h:53
 TQPathManager.h:54
 TQPathManager.h:55
 TQPathManager.h:56
 TQPathManager.h:57
 TQPathManager.h:58
 TQPathManager.h:59
 TQPathManager.h:60
 TQPathManager.h:61
 TQPathManager.h:62
 TQPathManager.h:63
 TQPathManager.h:64
 TQPathManager.h:65
 TQPathManager.h:66
 TQPathManager.h:67
 TQPathManager.h:68
 TQPathManager.h:69
 TQPathManager.h:70
 TQPathManager.h:71
 TQPathManager.h:72
 TQPathManager.h:73
 TQPathManager.h:74
 TQPathManager.h:75
 TQPathManager.h:76
 TQPathManager.h:77
 TQPathManager.h:78
 TQPathManager.h:79
 TQPathManager.h:80
 TQPathManager.h:81
 TQPathManager.h:82
 TQPathManager.h:83
 TQPathManager.h:84
 TQPathManager.h:85
 TQPathManager.h:86
 TQPathManager.h:87
 TQPathManager.h:88
 TQPathManager.h:89
 TQPathManager.h:90
 TQPathManager.h:91
 TQPathManager.h:92
 TQPathManager.h:93
 TQPathManager.h:94
 TQPathManager.h:95
 TQPathManager.h:96
 TQPathManager.h:97
 TQPathManager.h:98
 TQPathManager.h:99
 TQPathManager.h:100
 TQPathManager.h:101
 TQPathManager.h:102
 TQPathManager.h:103
 TQPathManager.h:104
 TQPathManager.h:105
 TQPathManager.h:106
 TQPathManager.h:107
 TQPathManager.h:108
 TQPathManager.h:109
 TQPathManager.h:110
 TQPathManager.h:111
 TQPathManager.h:112
 TQPathManager.h:113
 TQPathManager.h:114
 TQPathManager.h:115
 TQPathManager.h:116
 TQPathManager.h:117
 TQPathManager.h:118
 TQPathManager.h:119
 TQPathManager.h:120
 TQPathManager.h:121
 TQPathManager.h:122
 TQPathManager.h:123
 TQPathManager.h:124
 TQPathManager.h:125
 TQPathManager.h:126
 TQPathManager.h:127
 TQPathManager.h:128
 TQPathManager.h:129
 TQPathManager.h:130
 TQPathManager.h:131
 TQPathManager.h:132
 TQPathManager.h:133
 TQPathManager.h:134
 TQPathManager.h:135
 TQPathManager.h:136
 TQPathManager.h:137
 TQPathManager.h:138
 TQPathManager.h:139
 TQPathManager.h:140
 TQPathManager.h:141
 TQPathManager.h:142
 TQPathManager.h:143
 TQPathManager.h:144
 TQPathManager.h:145
 TQPathManager.h:146
 TQPathManager.h:147
 TQPathManager.h:148
 TQPathManager.h:149
 TQPathManager.h:150
 TQPathManager.h:151
 TQPathManager.h:152
 TQPathManager.h:153
 TQPathManager.h:154
 TQPathManager.h:155
 TQPathManager.h:156
 TQPathManager.h:157
 TQPathManager.h:158
 TQPathManager.h:159
 TQPathManager.h:160
 TQPathManager.h:161
 TQPathManager.h:162
 TQPathManager.h:163
 TQPathManager.h:164