/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc.

  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 "cmCTestSVN.h"

#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLSafe.h"

#include <cmsys/RegularExpression.hxx>

struct cmCTestSVN::Revision: public cmCTestVC::Revision
{
  cmCTestSVN::SVNInfo* SVNInfo;
};

//----------------------------------------------------------------------------
cmCTestSVN::cmCTestSVN(cmCTest* ct, std::ostream& log):
  cmCTestGlobalVC(ct, log)
{
  this->PriorRev = this->Unknown;
}

//----------------------------------------------------------------------------
cmCTestSVN::~cmCTestSVN()
{
}

//----------------------------------------------------------------------------
void cmCTestSVN::CleanupImpl()
{
  std::vector<const char*> svn_cleanup;
  svn_cleanup.push_back("cleanup");
  OutputLogger out(this->Log, "cleanup-out> ");
  OutputLogger err(this->Log, "cleanup-err> ");
  this->RunSVNCommand(svn_cleanup, &out, &err);
}

//----------------------------------------------------------------------------
class cmCTestSVN::InfoParser: public cmCTestVC::LineParser
{
public:
  InfoParser(cmCTestSVN* svn,
             const char* prefix,
             std::string& rev,
             SVNInfo& svninfo):
      Rev(rev), SVNRepo(svninfo)
    {
    this->SetLog(&svn->Log, prefix);
    this->RegexRev.compile("^Revision: ([0-9]+)");
    this->RegexURL.compile("^URL: +([^ ]+) *$");
    this->RegexRoot.compile("^Repository Root: +([^ ]+) *$");
    }
private:
  std::string& Rev;
  cmCTestSVN::SVNInfo& SVNRepo;
  cmsys::RegularExpression RegexRev;
  cmsys::RegularExpression RegexURL;
  cmsys::RegularExpression RegexRoot;
  virtual bool ProcessLine()
    {
    if(this->RegexRev.find(this->Line))
      {
      this->Rev = this->RegexRev.match(1);
      }
    else if(this->RegexURL.find(this->Line))
      {
      this->SVNRepo.URL = this->RegexURL.match(1);
      }
    else if(this->RegexRoot.find(this->Line))
      {
      this->SVNRepo.Root = this->RegexRoot.match(1);
      }
    return true;
    }
};

//----------------------------------------------------------------------------
static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2)
{
  // Does path p1 start with path p2?
  if(p1.size() == p2.size())
    {
    return p1 == p2;
    }
  else if(p1.size() > p2.size() && p1[p2.size()] == '/')
    {
    return strncmp(p1.c_str(), p2.c_str(), p2.size()) == 0;
    }
  else
    {
    return false;
    }
}

//----------------------------------------------------------------------------
std::string cmCTestSVN::LoadInfo(SVNInfo& svninfo)
{
  // Run "svn info" to get the repository info from the work tree.
  std::vector<const char*> svn_info;
  svn_info.push_back("info");
  svn_info.push_back(svninfo.LocalPath.c_str());
  std::string rev;
  InfoParser out(this, "info-out> ", rev, svninfo);
  OutputLogger err(this->Log, "info-err> ");
  this->RunSVNCommand(svn_info, &out, &err);
  return rev;
}

//----------------------------------------------------------------------------
void cmCTestSVN::NoteOldRevision()
{
  // Info for root repository
  this->Repositories.push_back( SVNInfo("") );
  this->RootInfo = &(this->Repositories.back());
  // Info for the external repositories
  this->LoadExternals();

  // Get info for all the repositories
  std::list<SVNInfo>::iterator itbeg = this->Repositories.begin();
  std::list<SVNInfo>::iterator itend = this->Repositories.end();
  for( ; itbeg != itend ; itbeg++)
    {
    SVNInfo& svninfo = *itbeg;
    svninfo.OldRevision = this->LoadInfo(svninfo);
    this->Log << "Revision for repository '" << svninfo.LocalPath
              << "' before update: " << svninfo.OldRevision << "\n";
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   Old revision of external repository '"
               << svninfo.LocalPath << "' is: "
               << svninfo.OldRevision << "\n");
    }

  // Set the global old revision to the one of the root
  this->OldRevision = this->RootInfo->OldRevision;
  this->PriorRev.Rev = this->OldRevision;
}

//----------------------------------------------------------------------------
void cmCTestSVN::NoteNewRevision()
{
  // Get info for the external repositories
  std::list<SVNInfo>::iterator itbeg = this->Repositories.begin();
  std::list<SVNInfo>::iterator itend = this->Repositories.end();
  for( ; itbeg != itend ; itbeg++)
    {
    SVNInfo& svninfo = *itbeg;
    svninfo.NewRevision = this->LoadInfo(svninfo);
    this->Log << "Revision for repository '" << svninfo.LocalPath
              << "' after update: " << svninfo.NewRevision << "\n";
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   New revision of external repository '"
               << svninfo.LocalPath << "' is: "
               << svninfo.NewRevision << "\n");

    // svninfo.Root = ""; // uncomment to test GuessBase
    this->Log << "Repository '" << svninfo.LocalPath
              << "' URL = " << svninfo.URL << "\n";
    this->Log << "Repository '" << svninfo.LocalPath
              << "' Root = " << svninfo.Root << "\n";

    // Compute the base path the working tree has checked out under
    // the repository root.
    if(!svninfo.Root.empty()
       && cmCTestSVNPathStarts(svninfo.URL, svninfo.Root))
      {
      svninfo.Base = cmCTest::DecodeURL(
            svninfo.URL.substr(svninfo.Root.size()));
      svninfo.Base += "/";
      }
    this->Log << "Repository '" << svninfo.LocalPath
              << "' Base = " << svninfo.Base << "\n";

  }

  // Set the global new revision to the one of the root
  this->NewRevision = this->RootInfo->NewRevision;
}

//----------------------------------------------------------------------------
void cmCTestSVN::GuessBase(SVNInfo& svninfo,
                           std::vector<Change> const& changes)
{
  // Subversion did not give us a good repository root so we need to
  // guess the base path from the URL and the paths in a revision with
  // changes under it.

  // Consider each possible URL suffix from longest to shortest.
  for(std::string::size_type slash = svninfo.URL.find('/');
      svninfo.Base.empty() && slash != std::string::npos;
      slash = svninfo.URL.find('/', slash+1))
    {
    // If the URL suffix is a prefix of at least one path then it is the base.
    std::string base = cmCTest::DecodeURL(svninfo.URL.substr(slash));
    for(std::vector<Change>::const_iterator ci = changes.begin();
        svninfo.Base.empty() && ci != changes.end(); ++ci)
      {
      if(cmCTestSVNPathStarts(ci->Path, base))
        {
        svninfo.Base = base;
        }
      }
    }

  // We always append a slash so that we know paths beginning in the
  // base lie under its path.  If no base was found then the working
  // tree must be a checkout of the entire repo and this will match
  // the leading slash in all paths.
  svninfo.Base += "/";

  this->Log << "Guessed Base = " << svninfo.Base << "\n";
}

//----------------------------------------------------------------------------
class cmCTestSVN::UpdateParser: public cmCTestVC::LineParser
{
public:
  UpdateParser(cmCTestSVN* svn, const char* prefix): SVN(svn)
    {
    this->SetLog(&svn->Log, prefix);
    this->RegexUpdate.compile("^([ADUCGE ])([ADUCGE ])[B ] +(.+)$");
    }
private:
  cmCTestSVN* SVN;
  cmsys::RegularExpression RegexUpdate;

  bool ProcessLine()
    {
    if(this->RegexUpdate.find(this->Line))
      {
      this->DoPath(this->RegexUpdate.match(1)[0],
                   this->RegexUpdate.match(2)[0],
                   this->RegexUpdate.match(3));
      }
    return true;
    }

  void DoPath(char path_status, char prop_status, std::string const& path)
    {
    char status = (path_status != ' ')? path_status : prop_status;
    std::string dir = cmSystemTools::GetFilenamePath(path);
    std::string name = cmSystemTools::GetFilenameName(path);
    // See "svn help update".
    switch(status)
      {
      case 'G':
        this->SVN->Dirs[dir][name].Status = PathModified;
        break;
      case 'C':
        this->SVN->Dirs[dir][name].Status = PathConflicting;
        break;
      case 'A': case 'D': case 'U':
        this->SVN->Dirs[dir][name].Status = PathUpdated;
        break;
      case 'E': // TODO?
      case '?': case ' ': default:
        break;
      }
    }
};

//----------------------------------------------------------------------------
bool cmCTestSVN::UpdateImpl()
{
  // Get user-specified update options.
  std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
  if(opts.empty())
    {
    opts = this->CTest->GetCTestConfiguration("SVNUpdateOptions");
    }
  std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());

  // Specify the start time for nightly testing.
  if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
    {
    args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
    }

  std::vector<char const*> svn_update;
  svn_update.push_back("update");
  for(std::vector<cmStdString>::const_iterator ai = args.begin();
      ai != args.end(); ++ai)
    {
    svn_update.push_back(ai->c_str());
    }

  UpdateParser out(this, "up-out> ");
  OutputLogger err(this->Log, "up-err> ");
  return this->RunSVNCommand(svn_update, &out, &err);
}

//----------------------------------------------------------------------------
bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
    OutputParser* out, OutputParser* err)
{
  if(parameters.empty()) return false;

  std::vector<char const*> args;
  args.push_back(this->CommandLineTool.c_str());

  args.insert(args.end(), parameters.begin(), parameters.end());

  args.push_back("--non-interactive");

  std::string userOptions =
    this->CTest->GetCTestConfiguration("SVNOptions");

  std::vector<cmStdString> parsedUserOptions =
    cmSystemTools::ParseArguments(userOptions.c_str());
  for(std::vector<cmStdString>::iterator i = parsedUserOptions.begin();
      i != parsedUserOptions.end(); ++i)
    {
    args.push_back(i->c_str());
    }

  args.push_back(0);

  if(strcmp(parameters[0], "update") == 0)
    {
    return RunUpdateCommand(&args[0], out, err);
    }
  else
    {
    return RunChild(&args[0], out, err);
    }
}

//----------------------------------------------------------------------------
class cmCTestSVN::LogParser: public cmCTestVC::OutputLogger,
                             private cmXMLParser
{
public:
  LogParser(cmCTestSVN* svn, const char* prefix, SVNInfo& svninfo):
    OutputLogger(svn->Log, prefix), SVN(svn), SVNRepo(svninfo)
  { this->InitializeParser(); }
  ~LogParser() { this->CleanupParser(); }
private:
  cmCTestSVN* SVN;
  cmCTestSVN::SVNInfo& SVNRepo;

  typedef cmCTestSVN::Revision Revision;
  typedef cmCTestSVN::Change Change;
  Revision Rev;
  std::vector<Change> Changes;
  Change CurChange;
  std::vector<char> CData;

  virtual bool ProcessChunk(const char* data, int length)
    {
    this->OutputLogger::ProcessChunk(data, length);
    this->ParseChunk(data, length);
    return true;
    }

  virtual void StartElement(const char* name, const char** atts)
    {
    this->CData.clear();
    if(strcmp(name, "logentry") == 0)
      {
      this->Rev = Revision();
      this->Rev.SVNInfo = &SVNRepo;
      if(const char* rev = this->FindAttribute(atts, "revision"))
        {
        this->Rev.Rev = rev;
        }
      this->Changes.clear();
      }
    else if(strcmp(name, "path") == 0)
      {
      this->CurChange = Change();
      if(const char* action = this->FindAttribute(atts, "action"))
        {
        this->CurChange.Action = action[0];
        }
      }
    }

  virtual void CharacterDataHandler(const char* data, int length)
    {
    this->CData.insert(this->CData.end(), data, data+length);
    }

  virtual void EndElement(const char* name)
    {
    if(strcmp(name, "logentry") == 0)
      {
      this->SVN->DoRevisionSVN(this->Rev, this->Changes);
      }
    else if(strcmp(name, "path") == 0 && !this->CData.empty())
      {
      std::string orig_path(&this->CData[0], this->CData.size());
      std::string new_path = SVNRepo.BuildLocalPath( orig_path );
      this->CurChange.Path.assign(new_path);
      this->Changes.push_back(this->CurChange);
      }
    else if(strcmp(name, "author") == 0 && !this->CData.empty())
      {
      this->Rev.Author.assign(&this->CData[0], this->CData.size());
      }
    else if(strcmp(name, "date") == 0 && !this->CData.empty())
      {
      this->Rev.Date.assign(&this->CData[0], this->CData.size());
      }
    else if(strcmp(name, "msg") == 0 && !this->CData.empty())
      {
      this->Rev.Log.assign(&this->CData[0], this->CData.size());
      }
    this->CData.clear();
    }

  virtual void ReportError(int, int, const char* msg)
    {
    this->SVN->Log << "Error parsing svn log xml: " << msg << "\n";
    }
};

//----------------------------------------------------------------------------
void cmCTestSVN::LoadRevisions()
{
  // Get revisions for all the external repositories
  std::list<SVNInfo>::iterator itbeg = this->Repositories.begin();
  std::list<SVNInfo>::iterator itend = this->Repositories.end();
  for( ; itbeg != itend ; itbeg++)
    {
    SVNInfo& svninfo = *itbeg;
    LoadRevisions(svninfo);
    }
}

//----------------------------------------------------------------------------
void cmCTestSVN::LoadRevisions(SVNInfo &svninfo)
{
  // We are interested in every revision included in the update.
  std::string revs;
  if(atoi(svninfo.OldRevision.c_str()) < atoi(svninfo.NewRevision.c_str()))
    {
    revs = "-r" + svninfo.OldRevision + ":" + svninfo.NewRevision;
    }
  else
    {
    revs = "-r" + svninfo.NewRevision;
    }

  // Run "svn log" to get all global revisions of interest.
  std::vector<const char*> svn_log;
  svn_log.push_back("log");
  svn_log.push_back("--xml");
  svn_log.push_back("-v");
  svn_log.push_back(revs.c_str());
  svn_log.push_back(svninfo.LocalPath.c_str());
  LogParser out(this, "log-out> ", svninfo);
  OutputLogger err(this->Log, "log-err> ");
  this->RunSVNCommand(svn_log, &out, &err);
}

//----------------------------------------------------------------------------
void cmCTestSVN::DoRevisionSVN(Revision const& revision,
                               std::vector<Change> const& changes)
{
  // Guess the base checkout path from the changes if necessary.
  if(this->RootInfo->Base.empty() && !changes.empty())
    {
    this->GuessBase(*this->RootInfo, changes);
    }

  // Ignore changes in the old revision for external repositories
  if(revision.Rev == revision.SVNInfo->OldRevision
     && revision.SVNInfo->LocalPath != "")
    {
    return;
    }

  this->cmCTestGlobalVC::DoRevision(revision, changes);
}

//----------------------------------------------------------------------------
class cmCTestSVN::StatusParser: public cmCTestVC::LineParser
{
public:
  StatusParser(cmCTestSVN* svn, const char* prefix): SVN(svn)
    {
    this->SetLog(&svn->Log, prefix);
    this->RegexStatus.compile("^([ACDIMRX?!~ ])([CM ])[ L]... +(.+)$");
    }
private:
  cmCTestSVN* SVN;
  cmsys::RegularExpression RegexStatus;
  bool ProcessLine()
    {
    if(this->RegexStatus.find(this->Line))
      {
      this->DoPath(this->RegexStatus.match(1)[0],
                   this->RegexStatus.match(2)[0],
                   this->RegexStatus.match(3));
      }
    return true;
    }

  void DoPath(char path_status, char prop_status, std::string const& path)
    {
    char status = (path_status != ' ')? path_status : prop_status;
    // See "svn help status".
    switch(status)
      {
      case 'M': case '!': case 'A': case 'D': case 'R':
        this->SVN->DoModification(PathModified, path);
        break;
      case 'C': case '~':
        this->SVN->DoModification(PathConflicting, path);
        break;
      case 'X': case 'I': case '?': case ' ': default:
        break;
      }
    }
};

//----------------------------------------------------------------------------
void cmCTestSVN::LoadModifications()
{
  // Run "svn status" which reports local modifications.
  std::vector<const char*> svn_status;
  svn_status.push_back("status");
  StatusParser out(this, "status-out> ");
  OutputLogger err(this->Log, "status-err> ");
  this->RunSVNCommand(svn_status, &out, &err);
}

//----------------------------------------------------------------------------
void cmCTestSVN::WriteXMLGlobal(std::ostream& xml)
{
  this->cmCTestGlobalVC::WriteXMLGlobal(xml);

  xml << "\t<SVNPath>" << this->RootInfo->Base << "</SVNPath>\n";
}

//----------------------------------------------------------------------------
class cmCTestSVN::ExternalParser: public cmCTestVC::LineParser
{
public:
  ExternalParser(cmCTestSVN* svn, const char* prefix): SVN(svn)
    {
    this->SetLog(&svn->Log, prefix);
    this->RegexExternal.compile("^X..... +(.+)$");
    }
private:
  cmCTestSVN* SVN;
  cmsys::RegularExpression RegexExternal;
  bool ProcessLine()
    {
    if(this->RegexExternal.find(this->Line))
      {
      this->DoPath(this->RegexExternal.match(1));
      }
    return true;
    }

  void DoPath(std::string const& path)
    {
    // Get local path relative to the source directory
    std::string local_path;
    if(path.size() > this->SVN->SourceDirectory.size() &&
       strncmp(path.c_str(), this->SVN->SourceDirectory.c_str(),
               this->SVN->SourceDirectory.size()) == 0)
      {
      local_path = path.c_str() + this->SVN->SourceDirectory.size() + 1;
      }
    else
      {
      local_path = path;
      }
    this->SVN->Repositories.push_back( SVNInfo(local_path.c_str()) );
    }
};

//----------------------------------------------------------------------------
void cmCTestSVN::LoadExternals()
{
  // Run "svn status" to get the list of external repositories
  std::vector<const char*> svn_status;
  svn_status.push_back("status");
  ExternalParser out(this, "external-out> ");
  OutputLogger err(this->Log, "external-err> ");
  this->RunSVNCommand(svn_status, &out, &err);
}

//----------------------------------------------------------------------------
std::string cmCTestSVN::SVNInfo::BuildLocalPath(std::string const& path) const
{
  std::string local_path;

  // Add local path prefix if not empty
  if (!this->LocalPath.empty())
    {
    local_path += this->LocalPath;
    local_path += "/";
    }

  // Add path with base prefix removed
  if(path.size() > this->Base.size() &&
     strncmp(path.c_str(), this->Base.c_str(), this->Base.size()) == 0)
    {
    local_path += (path.c_str() + this->Base.size());
    }
  else
    {
    local_path += path;
  }

  return local_path;
}
