/***************************************************************************
   copyright            : (C) 2007 by David Nolden
   email                : david.nolden.kdevelop@art-master.de
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#ifndef INCLUDEPATHRESOLVER_H
#define INCLUDEPATHRESOLVER_H
#include <tqstring.h> /* defines TQString */
#include <tqmap.h>

namespace CppTools {
  class FileModificationTimeWrapper;
  
  struct PathResolutionResult {
    PathResolutionResult( bool _success = false, const TQString& _errorMessage = TQString(), const TQString& _longErrorMessage = TQString() ) : success( _success ), errorMessage( _errorMessage ), longErrorMessage( _longErrorMessage )  {
    }
    bool success;
    TQString errorMessage;
    TQString longErrorMessage;
    
    TQStringList path;

    operator bool() const {
      return success;
    };
  };

  class SourcePathInformation;

  ///One resolution-try can issue up to 4 make-calls in worst case
  class IncludePathResolver {
    public:
      ///Whether the TQt event-loop should be continued(using BlockingKProcess). This crashes if enabled in a non-foreground thread.
      IncludePathResolver( bool continueEventLoop = false );
      ///Same as below, but uses the directory of the file as working-directory. The argument must be absolute.
      PathResolutionResult resolveIncludePath( const TQString& file );
      ///The include-path is only computed once for a whole directory, then it is cached using the modification-time of the Makefile.
      PathResolutionResult resolveIncludePath( const TQString& file, const TQString& workingDirectory );
      ///source and build must be absolute paths
      void setOutOfSourceBuildSystem( const TQString& source, const TQString& build );
    private:
      bool m_isResolving;
      bool m_continueEventLoop;
      struct CacheEntry {
        CacheEntry() : failed(false) {
        }
        TQDateTime modificationTime;
        TQStringList path;
        TQString errorMessage, longErrorMessage;
        bool failed;
        TQMap<TQString,bool> failedFiles;
        TQDateTime failTime;
      };
      typedef TQMap<TQString, CacheEntry> Cache;
      Cache m_cache;

      ///Executes the command, either using popen or BlockingKProcess
      PathResolutionResult getFullOutput( const TQString& command, const TQString& workingDirectory, TQString& output ) const;
      bool executeCommandPopen ( const TQString& command, const TQString& workingDirectory, TQString& result ) const;
      ///file should be the name of the target, without extension(because that may be different)
      PathResolutionResult resolveIncludePathInternal( const TQString& file, const TQString& workingDirectory, const TQString& makeParameters, const SourcePathInformation& source );
      bool m_outOfSource;
      TQString m_source;
      TQString m_build;
  };
};

#endif