/*============================================================================
  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,
    PartUpload,
    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();

  //! tar/gzip and then base 64 encode a file
  std::string Base64GzipEncodeFile(std::string file);
  //! base64 encode a file
  std::string Base64EncodeFile(std::string file);

  /**
   * Return the time remaining 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 ShouldPrintLabels() { return this->PrintLabels; }

  bool ShouldCompressTestOutput();
  bool ShouldCompressMemCheckOutput();
  bool CompressString(std::string& str);

  std::string GetCDashVersion();

  std::string GetStopTime() { return this->StopTime; }
  void SetStopTime(std::string time);

  //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);

  //! Clean/make safe for xml the given value such that it may be used as
  // one of the key fields by CDash when computing the buildid.
  static std::string SafeBuildIdField(const std::string& value);

  //! 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::ostream& 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);

  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; }
  int GetDropSiteCDash() { return this->DropSiteCDash; }

  //! 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;}

  std::string GetCostDataFile();

  const std::map<std::string, std::string> &GetDefinitions()
    {
    return this->Definitions;
    }

private:
  std::string ConfigType;
  std::string ScheduleType;
  std::string StopTime;
  bool NextDayStopTime;
  bool Verbose;
  bool ExtraVerbose;
  bool ProduceXML;
  bool LabelSummary;
  bool UseHTTP10;
  bool PrintLabels;
  bool Failover;
  bool BatchJobs;

  bool ForceNewCTestProcess;

  bool RunConfigurationScript;

  //flag for lazy getter (optimization)
  bool ComputedCompressTestOutput;
  bool ComputedCompressMemCheckOutput;

  int GenerateNotesFile(const char* files);

  void DetermineNextDayStop();

  // 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                     LastStopTimeout;

  int                     MaxTestNameWidth;

  int                     ParallelLevel;
  bool                    ParallelLevelSetInCli;

  int                     CompatibilityMode;

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

  std::string              NotesFiles;


  bool                     InteractiveDebugMode;

  bool                     ShortDateFormat;

  bool                     CompressXMLFiles;
  bool                     CompressTestOutput;
  bool                     CompressMemCheckOutput;

  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);

  //! read as "emit an error message for an unknown -D value"
  void ErrorMessageUnknownDashDValue(std::string &val);

  //! add a variable definition from a command line -D value
  bool AddVariableDefinition(const std::string &arg);

  //! 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 note from files.
  int GenerateCTestNotesOutput(std::ostream& os,
    const VectorOfStrings& files);

  //! 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;
  bool DropSiteCDash;

  std::vector<cmStdString> InitialCommandLineArguments;

  int SubmitIndex;

  cmGeneratedFileStream* OutputLogFile;
  int OutputLogFileLastTag;

  bool OutputTestOutputOnTestFailure;

  std::map<std::string, std::string> Definitions;
};

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
