/*============================================================================
  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.
============================================================================*/

#include "cmCTestUpdateHandler.h"

#include "cmCTest.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmXMLParser.h"
#include "cmXMLSafe.h"

#include "cmCTestVC.h"
#include "cmCTestCVS.h"
#include "cmCTestSVN.h"
#include "cmCTestBZR.h"
#include "cmCTestGIT.h"
#include "cmCTestHG.h"
#include "cmCTestP4.h"

#include <cmsys/auto_ptr.hxx>

//#include <cmsys/RegularExpression.hxx>
#include <cmsys/Process.h>

// used for sleep
#ifdef _WIN32
#include "windows.h"
#endif

#include <stdlib.h>
#include <math.h>
#include <float.h>

//----------------------------------------------------------------------
static const char* cmCTestUpdateHandlerUpdateStrings[] =
{
  "Unknown",
  "CVS",
  "SVN",
  "BZR",
  "GIT",
  "HG",
  "P4"
};

static const char* cmCTestUpdateHandlerUpdateToString(int type)
{
  if ( type < cmCTestUpdateHandler::e_UNKNOWN ||
    type >= cmCTestUpdateHandler::e_LAST )
    {
    return cmCTestUpdateHandlerUpdateStrings[cmCTestUpdateHandler::e_UNKNOWN];
    }
  return cmCTestUpdateHandlerUpdateStrings[type];
}

class cmCTestUpdateHandlerLocale
{
public:
  cmCTestUpdateHandlerLocale();
  ~cmCTestUpdateHandlerLocale();
private:
  std::string saveLCMessages;
};

cmCTestUpdateHandlerLocale::cmCTestUpdateHandlerLocale()
{
  const char* lcmess = cmSystemTools::GetEnv("LC_MESSAGES");
  if(lcmess)
    {
    saveLCMessages = lcmess;
    }
  // if LC_MESSAGES is not set to C, then
  // set it, so that svn/cvs info will be in english ascii
  if(! (lcmess && strcmp(lcmess, "C") == 0))
    {
    cmSystemTools::PutEnv("LC_MESSAGES=C");
    }
}

cmCTestUpdateHandlerLocale::~cmCTestUpdateHandlerLocale()
{
  // restore the value of LC_MESSAGES after running the version control
  // commands
  if(saveLCMessages.size())
    {
    std::string put = "LC_MESSAGES=";
    put += saveLCMessages;
    cmSystemTools::PutEnv(put.c_str());
    }
  else
    {
    cmSystemTools::UnsetEnv("LC_MESSAGES");
    }
}

//----------------------------------------------------------------------
cmCTestUpdateHandler::cmCTestUpdateHandler()
{
}

//----------------------------------------------------------------------
void cmCTestUpdateHandler::Initialize()
{
  this->Superclass::Initialize();
  this->UpdateCommand = "";
  this->UpdateType = e_CVS;
}

//----------------------------------------------------------------------
int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
{
  cmCTestLog(this->CTest, DEBUG, "Determine update type from command: " << cmd
    << " and type: " << type << std::endl);
  if ( type && *type )
    {
    cmCTestLog(this->CTest, DEBUG, "Type specified: " << type << std::endl);
    std::string stype = cmSystemTools::LowerCase(type);
    if ( stype.find("cvs") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_CVS;
      }
    if ( stype.find("svn") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_SVN;
      }
    if ( stype.find("bzr") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_BZR;
      }
    if ( stype.find("git") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_GIT;
      }
    if ( stype.find("hg") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_HG;
      }
    if ( stype.find("p4") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_P4;
      }
    }
  else
    {
    cmCTestLog(this->CTest, DEBUG, "Type not specified, check command: "
      << cmd << std::endl);
    std::string stype = cmSystemTools::LowerCase(cmd);
    if ( stype.find("cvs") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_CVS;
      }
    if ( stype.find("svn") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_SVN;
      }
    if ( stype.find("bzr") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_BZR;
      }
    if ( stype.find("git") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_GIT;
      }
    if ( stype.find("hg") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_HG;
      }
    if ( stype.find("p4") != std::string::npos )
      {
      return cmCTestUpdateHandler::e_P4;
      }
    }
  return cmCTestUpdateHandler::e_UNKNOWN;
}

//----------------------------------------------------------------------
//clearly it would be nice if this were broken up into a few smaller
//functions and commented...
int cmCTestUpdateHandler::ProcessHandler()
{
  // Make sure VCS tool messages are in English so we can parse them.
  cmCTestUpdateHandlerLocale fixLocale;
  static_cast<void>(fixLocale);

  // Get source dir
  const char* sourceDirectory = this->GetOption("SourceDirectory");
  if ( !sourceDirectory )
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
      "Cannot find SourceDirectory  key in the DartConfiguration.tcl"
      << std::endl);
    return -1;
    }

  cmGeneratedFileStream ofs;
  if ( !this->CTest->GetShowOnly() )
    {
    this->StartLogFile("Update", ofs);
    }

  cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Updating the repository: "
    << sourceDirectory << std::endl);

  if(!this->SelectVCS())
    {
    return -1;
    }

  cmCTestLog(this->CTest, HANDLER_OUTPUT, "   Use "
    << cmCTestUpdateHandlerUpdateToString(this->UpdateType)
    << " repository type"
    << std::endl;);

  // Create an object to interact with the VCS tool.
  cmsys::auto_ptr<cmCTestVC> vc;
  switch (this->UpdateType)
    {
    case e_CVS: vc.reset(new cmCTestCVS(this->CTest, ofs)); break;
    case e_SVN: vc.reset(new cmCTestSVN(this->CTest, ofs)); break;
    case e_BZR: vc.reset(new cmCTestBZR(this->CTest, ofs)); break;
    case e_GIT: vc.reset(new cmCTestGIT(this->CTest, ofs)); break;
    case e_HG:  vc.reset(new cmCTestHG(this->CTest, ofs)); break;
    case e_P4:  vc.reset(new cmCTestP4(this->CTest, ofs)); break;
    default:    vc.reset(new cmCTestVC(this->CTest, ofs));  break;
    }
  vc->SetCommandLineTool(this->UpdateCommand);
  vc->SetSourceDirectory(sourceDirectory);

  // Cleanup the working tree.
  vc->Cleanup();

  //
  // Now update repository and remember what files were updated
  //
  cmGeneratedFileStream os;
  if(!this->StartResultingXML(cmCTest::PartUpdate, "Update", os))
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open log file"
      << std::endl);
    return -1;
    }
  std::string start_time = this->CTest->CurrentTime();
  unsigned int start_time_time =
    static_cast<unsigned int>(cmSystemTools::GetTime());
  double elapsed_time_start = cmSystemTools::GetTime();

  bool updated = vc->Update();

  os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    << "<Update mode=\"Client\" Generator=\"ctest-"
    << cmVersion::GetCMakeVersion() << "\">\n"
    << "\t<Site>" << this->CTest->GetCTestConfiguration("Site") << "</Site>\n"
    << "\t<BuildName>" << this->CTest->GetCTestConfiguration("BuildName")
    << "</BuildName>\n"
    << "\t<BuildStamp>" << this->CTest->GetCurrentTag() << "-"
    << this->CTest->GetTestModelString() << "</BuildStamp>" << std::endl;
  os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
    << "\t<StartTime>" << start_time_time << "</StartTime>\n"
    << "\t<UpdateCommand>"
     << cmXMLSafe(vc->GetUpdateCommandLine()).Quotes(false)
    << "</UpdateCommand>\n"
    << "\t<UpdateType>" << cmXMLSafe(
      cmCTestUpdateHandlerUpdateToString(this->UpdateType))
    << "</UpdateType>\n";

  vc->WriteXML(os);

  int localModifications = 0;
  int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
  if(numUpdated)
    {
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   Found " << numUpdated << " updated files\n");
    }
  if(int numModified = vc->GetPathCount(cmCTestVC::PathModified))
    {
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   Found " << numModified << " locally modified files\n");
    localModifications += numModified;
    }
  if(int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting))
    {
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   Found " << numConflicting << " conflicting files\n");
    localModifications += numConflicting;
    }

  cmCTestLog(this->CTest, DEBUG, "End" << std::endl);
  std::string end_time = this->CTest->CurrentTime();
  os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
     << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime())
     << "</EndTime>\n"
    << "<ElapsedMinutes>" <<
    static_cast<int>((cmSystemTools::GetTime() - elapsed_time_start)/6)/10.0
    << "</ElapsedMinutes>\n"
    << "\t<UpdateReturnStatus>";
  if(localModifications)
    {
    os << "Update error: There are modified or conflicting files in the "
      "repository";
    cmCTestLog(this->CTest, ERROR_MESSAGE,
      "   There are modified or conflicting files in the repository"
      << std::endl);
    }
  if(!updated)
    {
    os << "Update command failed:\n" << vc->GetUpdateCommandLine();
    cmCTestLog(this->CTest, ERROR_MESSAGE, "   Update command failed: "
               << vc->GetUpdateCommandLine() << "\n");
    }
  os << "</UpdateReturnStatus>" << std::endl;
  os << "</Update>" << std::endl;
  return numUpdated;
}

//----------------------------------------------------------------------
int cmCTestUpdateHandler::DetectVCS(const char* dir)
{
  std::string sourceDirectory = dir;
  cmCTestLog(this->CTest, DEBUG, "Check directory: "
    << sourceDirectory << std::endl);
  sourceDirectory += "/.svn";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_SVN;
    }
  sourceDirectory = dir;
  sourceDirectory += "/CVS";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_CVS;
    }
  sourceDirectory = dir;
  sourceDirectory += "/.bzr";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_BZR;
    }
  sourceDirectory = dir;
  sourceDirectory += "/.git";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_GIT;
    }
  sourceDirectory = dir;
  sourceDirectory += "/.hg";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_HG;
    }
  sourceDirectory = dir;
  sourceDirectory += "/.p4";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_P4;
    }
  sourceDirectory = dir;
  sourceDirectory += "/.p4config";
  if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
    {
    return cmCTestUpdateHandler::e_P4;
    }
  return cmCTestUpdateHandler::e_UNKNOWN;
}

//----------------------------------------------------------------------
bool cmCTestUpdateHandler::SelectVCS()
{
  // Get update command
  this->UpdateCommand = this->CTest->GetCTestConfiguration("UpdateCommand");

  // Detect the VCS managing the source tree.
  this->UpdateType = this->DetectVCS(this->GetOption("SourceDirectory"));
  if (this->UpdateType == e_UNKNOWN)
    {
    // The source tree does not have a recognized VCS.  Check the
    // configuration value or command name.
    this->UpdateType = this->DetermineType(this->UpdateCommand.c_str(),
      this->CTest->GetCTestConfiguration("UpdateType").c_str());
    }

  // If no update command was specified, lookup one for this VCS tool.
  if (this->UpdateCommand.empty())
    {
    const char* key = 0;
    switch (this->UpdateType)
      {
      case e_CVS: key = "CVSCommand"; break;
      case e_SVN: key = "SVNCommand"; break;
      case e_BZR: key = "BZRCommand"; break;
      case e_GIT: key = "GITCommand"; break;
      case e_HG:  key = "HGCommand";  break;
      case e_P4:  key = "P4Command";  break;
      default: break;
      }
    if (key)
      {
      this->UpdateCommand = this->CTest->GetCTestConfiguration(key);
      }
    if (this->UpdateCommand.empty())
      {
      cmOStringStream e;
      e << "Cannot find UpdateCommand ";
      if (key)
        {
        e << "or " << key;
        }
      e << " configuration key.";
      cmCTestLog(this->CTest, ERROR_MESSAGE, e.str() << std::endl);
      return false;
      }
    }

  return true;
}
