/*============================================================================
  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 std::string& name) { this->Name = name; }
    const std::string& GetName() const { return this->Name; }

    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<cmsys::String> VectorOfStrings;
  typedef std::set<std::string> 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 std::string& 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 std::string& definition,
    std::vector<std::string>& vec);
  void PopulateCustomInteger(cmMakefile* mf, const std::string& 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 std::string& 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 std::string& encstr);

  //! Create XML file that contains all the notes specified
  int GenerateNotesFile(const VectorOfStrings &files);

  //! Submit extra files to the server
  bool SubmitExtraFiles(const char* files);
  bool SubmitExtraFiles(const VectorOfStrings &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<std::string> &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<std::string,cmCTestGenericHandler*> t_TestingHandlers;
  t_TestingHandlers TestingHandlers;

  bool ShowOnly;

  //! Map of configuration properties
  typedef std::map<std::string, std::string> 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<std::string, 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<std::string> 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
