/*============================================================================
  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 cmCTest_h
#define cmCTest_h

#include "cmStandardIncludes.h"
#include "cmListFileCache.h"
#include <time.h>

class cmake;
class cmMakefile;
class cmCTestGenericHandler;
class cmGeneratedFileStream;
class cmCTestCommand;
class cmCTestScriptHandler;
class cmCTestStartCommand;

#define cmCTestLog(ctSelf, logType, msg) \
  do { \
  cmOStringStream cmCTestLog_msg; \
  cmCTestLog_msg << msg; \
  (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\
                cmCTestLog_msg.str().c_str());\
  } while ( 0 )

#ifdef cerr
#  undef cerr
#endif
#define cerr no_cerr_use_cmCTestLog

#ifdef cout
#  undef cout
#endif
#define cout no_cout_use_cmCTestLog

class cmCTest
{
  friend class cmCTestRunTest;
  friend class cmCTestMultiProcessHandler;
public:
  /** Enumerate parts of the testing and submission process.  */
  enum Part
  {
    PartStart,
    PartUpdate,
    PartConfigure,
    PartBuild,
    PartTest,
    PartCoverage,
    PartMemCheck,
    PartSubmit,
    PartNotes,
    PartExtraFiles,
    PartCount // Update names in constructor when adding a part
  };

  /** Representation of one part.  */
  struct PartInfo
  {
    PartInfo(): Enabled(false) {}

    void SetName(const char* name) { this->Name = name; }
    const char* GetName() const { return this->Name.c_str(); }

    void Enable() { this->Enabled = true; }
    operator bool() const { return this->Enabled; }

    std::vector<std::string> SubmitFiles;
  private:
    bool Enabled;
    std::string Name;
  };
#ifdef CMAKE_BUILD_WITH_CMAKE
  enum HTTPMethod {
    HTTP_GET,
    HTTP_POST,
    HTTP_PUT
  };

  /**
   * Perform an HTTP request.
   */
  static int HTTPRequest(std::string url, HTTPMethod method,
                          std::string& response,
                          std::string fields = "", 
                          std::string putFile = "", int timeout = 0);
#endif

  /** Get a testing part id from its string name.  Returns PartCount
      if the string does not name a valid part.  */
  Part GetPartFromName(const char* name);

  typedef std::vector<cmStdString> VectorOfStrings;
  typedef std::set<cmStdString> SetOfStrings;

  ///! Process Command line arguments
  int Run(std::vector<std::string> &, std::string* output = 0);

  /**
   * Initialize and finalize testing
   */
  bool InitializeFromCommand(cmCTestStartCommand* command);
  void Finalize();

  /**
   * Process the tests. This is the main routine. The execution of the
   * tests should look like this:
   *
   * ctest foo;
   * foo.Initialize();
   * // Set some things on foo
   * foo.ProcessTests();
   * foo.Finalize();
   */
  int ProcessTests();

  /*
   * A utility function that returns the nightly time
   */
  struct tm* GetNightlyTime(std::string str,
    bool tomorrowtag);

  /*
   * Is the tomorrow tag set?
   */
  bool GetTomorrowTag() { return this->TomorrowTag; };

  /**
   * Try to run tests of the project
   */
  int TestDirectory(bool memcheck);

  ///! what is the configuraiton type, e.g. Debug, Release etc.
  std::string const& GetConfigType();
  double GetTimeOut() { return this->TimeOut; }
  void SetTimeOut(double t) { this->TimeOut = t; }

  double GetGlobalTimeout() { return this->GlobalTimeout; }

  // how many test to run at the same time
  int GetParallelLevel() { return this->ParallelLevel; }
  void SetParallelLevel(int);

  /**
   * Check if CTest file exists
   */
  bool CTestFileExists(const std::string& filename);
  bool AddIfExists(Part part, const char* file);

  /**
   * Set the cmake test
   */
  bool SetTest(const char*, bool report = true);

  /**
   * Set the cmake test mode (experimental, nightly, continuous).
   */
  void SetTestModel(int mode);
  int GetTestModel() { return this->TestModel; };

  std::string GetTestModelString();
  static int GetTestModelFromString(const char* str);
  static std::string CleanString(const std::string& str);
  std::string GetCTestConfiguration(const char *name);
  void SetCTestConfiguration(const char *name, const char* value);
  void EmptyCTestConfiguration();

  /**
   * constructor and destructor
   */
  cmCTest();
  ~cmCTest();

  //! Set the notes files to be created.
  void SetNotesFiles(const char* notes);

  void PopulateCustomVector(cmMakefile* mf, const char* definition,
    VectorOfStrings& vec);
  void PopulateCustomInteger(cmMakefile* mf, const char* def,
    int& val);

  ///! Get the current time as string
  std::string CurrentTime();

  /** 
   * Return the time remaianing that the script is allowed to run in
   * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
   * not been set it returns 1e7 seconds
   */
  double GetRemainingTimeAllowed();
    
  ///! Open file in the output directory and set the stream
  bool OpenOutputFile(const std::string& path,
                      const std::string& name,
                      cmGeneratedFileStream& stream,
                      bool compress = false);

  ///! Should we only show what we would do?
  bool GetShowOnly();

  bool ShouldUseHTTP10() { return this->UseHTTP10; }

  bool ShouldCompressTestOutput();

  std::string GetCDashVersion();

  //Used for parallel ctest job scheduling
  std::string GetScheduleType() { return this->ScheduleType; }
  void SetScheduleType(std::string type) { this->ScheduleType = type; }

  ///! The max output width
  int GetMaxTestNameWidth() const;
  void SetMaxTestNameWidth(int w) { this->MaxTestNameWidth = w;}

  /**
   * Run a single executable command and put the stdout and stderr
   * in output.
   *
   * If verbose is false, no user-viewable output from the program
   * being run will be generated.
   *
   * If timeout is specified, the command will be terminated after
   * timeout expires. Timeout is specified in seconds.
   *
   * Argument retVal should be a pointer to the location where the
   * exit code will be stored. If the retVal is not specified and
   * the program exits with a code other than 0, then the this
   * function will return false.
   *
   * If the command has spaces in the path the caller MUST call
   * cmSystemTools::ConvertToRunCommandPath on the command before passing
   * it into this function or it will not work.  The command must be correctly
   * escaped for this to with spaces.
   */
  bool RunCommand(const char* command,
    std::string* stdOut, std::string* stdErr,
    int* retVal = 0, const char* dir = 0, double timeout = 0.0);

  //! Start CTest XML output file
  void StartXML(std::ostream& ostr, bool append);

  //! End CTest XML output file
  void EndXML(std::ostream& ostr);

  //! Run command specialized for make and configure. Returns process status
  // and retVal is return value or exception.
  int RunMakeCommand(const char* command, std::string* output,
    int* retVal, const char* dir, int timeout,
    std::ofstream& ofs);

  /*
   * return the current tag
   */
  std::string GetCurrentTag();

  //! Get the path to the build tree
  std::string GetBinaryDir();

  //! Get the short path to the file. This means if the file is in binary or
  //source directory, it will become /.../relative/path/to/file
  std::string GetShortPathToFile(const char* fname);

  //! Get the path to CTest
  const char* GetCTestExecutable() { return this->CTestSelf.c_str(); }
  const char* GetCMakeExecutable() { return this->CMakeSelf.c_str(); }

  enum {
    EXPERIMENTAL,
    NIGHTLY,
    CONTINUOUS
  };

  // provide some more detailed info on the return code for ctest
  enum {
    UPDATE_ERRORS    = 0x01,
    CONFIGURE_ERRORS = 0x02,
    BUILD_ERRORS     = 0x04,
    TEST_ERRORS      = 0x08,
    MEMORY_ERRORS    = 0x10,
    COVERAGE_ERRORS  = 0x20,
    SUBMIT_ERRORS    = 0x40
  };

  ///! Are we producing XML
  bool GetProduceXML();
  void SetProduceXML(bool v);

  //! Run command specialized for tests. Returns process status and retVal is
  // return value or exception. If environment is non-null, it is used to set
  // environment variables prior to running the test. After running the test,
  // environment variables are restored to their previous values.
  int RunTest(std::vector<const char*> args, std::string* output, int *retVal,
    std::ostream* logfile, double testTimeOut,
    std::vector<std::string>* environment);

  /**
   * Execute handler and return its result. If the handler fails, it returns
   * negative value.
   */
  int ExecuteHandler(const char* handler);

  /*
   * Get the handler object
   */
  cmCTestGenericHandler* GetHandler(const char* handler);
  cmCTestGenericHandler* GetInitializedHandler(const char* handler);

  /*
   * Set the CTest variable from CMake variable
   */
  bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
    const char* dconfig, const char* cmake_var);

  //! Make string safe to be send as an URL
  static std::string MakeURLSafe(const std::string&);

  /** Decode a URL to the original string.  */
  static std::string DecodeURL(const std::string&);

  //! Should ctect configuration be updated. When using new style ctest
  // script, this should be true.
  void SetSuppressUpdatingCTestConfiguration(bool val)
    {
    this->SuppressUpdatingCTestConfiguration = val;
    }

  //! Add overwrite to ctest configuration.
  // The format is key=value
  void AddCTestConfigurationOverwrite(const char* encstr);

  //! Create XML file that contains all the notes specified
  int GenerateNotesFile(const std::vector<cmStdString> &files);

  //! Submit extra files to the server
  bool SubmitExtraFiles(const char* files);
  bool SubmitExtraFiles(const std::vector<cmStdString> &files);

  //! Set the output log file name
  void SetOutputLogFileName(const char* name);

  //! Set the visual studio or Xcode config type
  void SetConfigType(const char* ct);

  //! Various log types
  enum {
    DEBUG = 0,
    OUTPUT,
    HANDLER_OUTPUT,
    HANDLER_VERBOSE_OUTPUT,
    WARNING,
    ERROR_MESSAGE,
    OTHER
  };

  //! Add log to the output
  void Log(int logType, const char* file, int line, const char* msg);

  //! Get the version of dart server
  int GetDartVersion() { return this->DartVersion; }

  //! Add file to be submitted
  void AddSubmitFile(Part part, const char* name);
  std::vector<std::string> const& GetSubmitFiles(Part part)
    { return this->Parts[part].SubmitFiles; }
  void ClearSubmitFiles(Part part) { this->Parts[part].SubmitFiles.clear(); }

  //! Read the custom configuration files and apply them to the current ctest
  int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf);

  std::vector<cmStdString> &GetInitialCommandLineArguments()
  { return this->InitialCommandLineArguments; };

  //! Set the track to submit to
  void SetSpecificTrack(const char* track);
  const char* GetSpecificTrack();

  void SetFailover(bool failover) { this->Failover = failover; }
  bool GetFailover() { return this->Failover; }

  void SetBatchJobs(bool batch = true) { this->BatchJobs = batch; }
  bool GetBatchJobs() { return this->BatchJobs; }

  bool GetVerbose() { return this->Verbose;}
  bool GetExtraVerbose() { return this->ExtraVerbose;}

  /** Direct process output to given streams.  */
  void SetStreams(std::ostream* out, std::ostream* err)
    { this->StreamOut = out; this->StreamErr = err; }
  void AddSiteProperties(std::ostream& );
  bool GetLabelSummary() { return this->LabelSummary;}
private:
  std::string ConfigType;
  std::string ScheduleType;
  bool Verbose;
  bool ExtraVerbose;
  bool ProduceXML;
  bool LabelSummary;
  bool UseHTTP10;
  bool Failover;
  bool BatchJobs;

  bool ForceNewCTestProcess;

  bool RunConfigurationScript;

  //flag for lazy getter (optimization)
  bool ComputedCompressOutput;

  int GenerateNotesFile(const char* files);

  // these are helper classes
  typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers;
  t_TestingHandlers TestingHandlers;

  bool ShowOnly;

  //! Map of configuration properties
  typedef std::map<cmStdString, cmStdString> CTestConfigurationMap;

  std::string             CTestConfigFile;
  // TODO: The ctest configuration should be a hierarchy of
  // configuration option sources: command-line, script, ini file.
  // Then the ini file can get re-loaded whenever it changes without
  // affecting any higher-precedence settings.
  CTestConfigurationMap CTestConfiguration;
  CTestConfigurationMap CTestConfigurationOverwrites;
  PartInfo                Parts[PartCount];
  typedef std::map<cmStdString, Part> PartMapType;
  PartMapType             PartMap;

  std::string             CurrentTag;
  bool                    TomorrowTag;

  int                     TestModel;
  std::string             SpecificTrack;

  double                  TimeOut;

  double                  GlobalTimeout;

  int                     MaxTestNameWidth;

  int                     ParallelLevel;

  int                     CompatibilityMode;

  // information for the --build-and-test options
  std::string              CMakeSelf;
  std::string              CTestSelf;
  std::string              BinaryDir;

  std::string              NotesFiles;


  bool                     InteractiveDebugMode;

  bool                     ShortDateFormat;

  bool                     CompressXMLFiles;

  bool                     CompressTestOutput;

  void InitStreams();
  std::ostream* StreamOut;
  std::ostream* StreamErr;

  void BlockTestErrorDiagnostics();

  /**
   * Initialize a dashboard run in the given build tree.  The "command"
   * argument is non-NULL when running from a command-driven (ctest_start)
   * dashboard script, and NULL when running from the CTest command
   * line.  Note that a declarative dashboard script does not actually
   * call this method because it sets CTEST_COMMAND to drive a build
   * through the ctest command line.
   */
  int Initialize(const char* binary_dir, cmCTestStartCommand* command);

  //! parse the option after -D and convert it into the appropriate steps
  bool AddTestsForDashboardType(std::string &targ);

  //! parse and process most common command line arguments
  void HandleCommandLineArguments(size_t &i, 
                                  std::vector<std::string> &args);

  //! hande the -S -SP and -SR arguments
  void HandleScriptArguments(size_t &i, 
                             std::vector<std::string> &args,
                             bool &SRArgumentSpecified);

  //! Reread the configuration file
  bool UpdateCTestConfiguration();

  //! Create not from files.
  int GenerateCTestNotesOutput(std::ostream& os,
    const VectorOfStrings& files);

  ///! Find the running cmake
  void FindRunningCMake();

  //! Check if the argument is the one specified
  bool CheckArgument(const std::string& arg, const char* varg1,
    const char* varg2 = 0);

  //! Output errors from a test
  void OutputTestErrors(std::vector<char> const &process_output);

  bool                      SuppressUpdatingCTestConfiguration;

  bool Debug;
  bool ShowLineNumbers;
  bool Quiet;

  int  DartVersion;

  std::vector<cmStdString> InitialCommandLineArguments;

  int SubmitIndex;

  cmGeneratedFileStream* OutputLogFile;
  int OutputLogFileLastTag;

  bool OutputTestOutputOnTestFailure;
};

class cmCTestLogWrite
{
public:
  cmCTestLogWrite(const char* data, size_t length)
    : Data(data), Length(length) {}

  const char* Data;
  size_t Length;
};

inline std::ostream& operator<< (std::ostream& os, const cmCTestLogWrite& c)
{
  if (!c.Length)
    {
    return os;
    }
  os.write(c.Data, c.Length);
  os.flush();
  return os;
}

#endif
