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

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

#include <cmsys/RegularExpression.hxx>

//----------------------------------------------------------------------------
cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log): cmCTestVC(ct, log)
{
}

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

//----------------------------------------------------------------------------
class cmCTestCVS::UpdateParser: public cmCTestVC::LineParser
{
public:
  UpdateParser(cmCTestCVS* cvs, const char* prefix): CVS(cvs)
    {
    this->SetLog(&cvs->Log, prefix);
    // See "man cvs", section "update output".
    this->RegexFileUpdated.compile("^([UP])  *(.*)");
    this->RegexFileModified.compile("^([MRA])  *(.*)");
    this->RegexFileConflicting.compile("^([C])  *(.*)");
    this->RegexFileRemoved1.compile(
      "cvs[^ ]* update: `?([^']*)'? is no longer in the repository");
    this->RegexFileRemoved2.compile(
      "cvs[^ ]* update: "
      "warning: `?([^']*)'? is not \\(any longer\\) pertinent");
    }
private:
  cmCTestCVS* CVS;
  cmsys::RegularExpression RegexFileUpdated;
  cmsys::RegularExpression RegexFileModified;
  cmsys::RegularExpression RegexFileConflicting;
  cmsys::RegularExpression RegexFileRemoved1;
  cmsys::RegularExpression RegexFileRemoved2;

  virtual bool ProcessLine()
    {
    if(this->RegexFileUpdated.find(this->Line))
      {
      this->DoFile(PathUpdated, this->RegexFileUpdated.match(2));
      }
    else if(this->RegexFileModified.find(this->Line))
      {
      this->DoFile(PathModified, this->RegexFileModified.match(2));
      }
    else if(this->RegexFileConflicting.find(this->Line))
      {
      this->DoFile(PathConflicting, this->RegexFileConflicting.match(2));
      }
    else if(this->RegexFileRemoved1.find(this->Line))
      {
      this->DoFile(PathUpdated, this->RegexFileRemoved1.match(1));
      }
    else if(this->RegexFileRemoved2.find(this->Line))
      {
      this->DoFile(PathUpdated, this->RegexFileRemoved2.match(1));
      }
    return true;
    }

  void DoFile(PathStatus status, std::string const& file)
    {
    std::string dir = cmSystemTools::GetFilenamePath(file);
    std::string name = cmSystemTools::GetFilenameName(file);
    this->CVS->Dirs[dir][name] = status;
    }
};

//----------------------------------------------------------------------------
bool cmCTestCVS::UpdateImpl()
{
  // Get user-specified update options.
  std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
  if(opts.empty())
    {
    opts = this->CTest->GetCTestConfiguration("CVSUpdateOptions");
    if(opts.empty())
      {
      opts = "-dP";
      }
    }
  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("-D" + this->GetNightlyTime() + " UTC");
    }

  // Run "cvs update" to update the work tree.
  std::vector<char const*> cvs_update;
  cvs_update.push_back(this->CommandLineTool.c_str());
  cvs_update.push_back("-z3");
  cvs_update.push_back("update");
  for(std::vector<cmStdString>::const_iterator ai = args.begin();
      ai != args.end(); ++ai)
    {
    cvs_update.push_back(ai->c_str());
    }
  cvs_update.push_back(0);

  UpdateParser out(this, "up-out> ");
  UpdateParser err(this, "up-err> ");
  return this->RunUpdateCommand(&cvs_update[0], &out, &err);
}

//----------------------------------------------------------------------------
class cmCTestCVS::LogParser: public cmCTestVC::LineParser
{
public:
  typedef cmCTestCVS::Revision Revision;
  LogParser(cmCTestCVS* cvs, const char* prefix, std::vector<Revision>& revs):
    CVS(cvs), Revisions(revs), Section(SectionHeader)
    {
    this->SetLog(&cvs->Log, prefix),
    this->RegexRevision.compile("^revision +([^ ]*) *$");
    this->RegexBranches.compile("^branches: .*$");
    this->RegexPerson.compile("^date: +([^;]+); +author: +([^;]+);");
    }
private:
  cmCTestCVS* CVS;
  std::vector<Revision>& Revisions;
  cmsys::RegularExpression RegexRevision;
  cmsys::RegularExpression RegexBranches;
  cmsys::RegularExpression RegexPerson;
  enum SectionType { SectionHeader, SectionRevisions, SectionEnd };
  SectionType Section;
  Revision Rev;

  virtual bool ProcessLine()
    {
    if(this->Line == ("======================================="
                      "======================================"))
      {
      // This line ends the revision list.
      if(this->Section == SectionRevisions)
        {
        this->FinishRevision();
        }
      this->Section = SectionEnd;
      }
    else if(this->Line == "----------------------------")
      {
      // This line divides revisions from the header and each other.
      if(this->Section == SectionHeader)
        {
        this->Section = SectionRevisions;
        }
      else if(this->Section == SectionRevisions)
        {
        this->FinishRevision();
        }
      }
    else if(this->Section == SectionRevisions)
      {
      if(!this->Rev.Log.empty())
        {
        // Continue the existing log.
        this->Rev.Log += this->Line;
        this->Rev.Log += "\n";
        }
      else if(this->Rev.Rev.empty() && this->RegexRevision.find(this->Line))
        {
        this->Rev.Rev = this->RegexRevision.match(1);
        }
      else if(this->Rev.Date.empty() && this->RegexPerson.find(this->Line))
        {
        this->Rev.Date = this->RegexPerson.match(1);
        this->Rev.Author = this->RegexPerson.match(2);
        }
      else if(!this->RegexBranches.find(this->Line))
        {
        // Start the log.
        this->Rev.Log += this->Line;
        this->Rev.Log += "\n";
        }
      }
    return this->Section != SectionEnd;
    }

  void FinishRevision()
    {
    if(!this->Rev.Rev.empty())
      {
      // Record this revision.
      this->CVS->Log << "Found revision " << this->Rev.Rev << "\n"
                     << "  author = " << this->Rev.Author << "\n"
                     << "  date = " << this->Rev.Date << "\n";
      this->Revisions.push_back(this->Rev);

      // We only need two revisions.
      if(this->Revisions.size() >= 2)
        {
        this->Section = SectionEnd;
        }
      }
    this->Rev = Revision();
    }
};

//----------------------------------------------------------------------------
std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir)
{
  // Compute the tag file location for this directory.
  std::string tagFile = this->SourceDirectory;
  if(!dir.empty())
    {
    tagFile += "/";
    tagFile += dir;
    }
  tagFile += "/CVS/Tag";

  // Lookup the branch in the tag file, if any.
  std::string tagLine;
  std::ifstream tagStream(tagFile.c_str());
  if(tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) &&
     tagLine.size() > 1 && tagLine[0] == 'T')
    {
    // Use the branch specified in the tag file.
    std::string flag = "-r";
    flag += tagLine.substr(1);
    return flag;
    }
  else
    {
    // Use the default branch.
    return "-b";
    }
}

//----------------------------------------------------------------------------
void cmCTestCVS::LoadRevisions(std::string const& file,
                               const char* branchFlag,
                               std::vector<Revision>& revisions)
{
  cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);

  // Run "cvs log" to get revisions of this file on this branch.
  const char* cvs = this->CommandLineTool.c_str();
  const char* cvs_log[] =
    {cvs, "log", "-N", branchFlag, file.c_str(), 0};

  LogParser out(this, "log-out> ", revisions);
  OutputLogger err(this->Log, "log-err> ");
  this->RunChild(cvs_log, &out, &err);
}

//----------------------------------------------------------------------------
void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
                                   std::string const& path,
                                   Directory const& dir)
{
  const char* slash = path.empty()? "":"/";
  xml << "\t<Directory>\n"
      << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";

  // Lookup the branch checked out in the working tree.
  std::string branchFlag = this->ComputeBranchFlag(path);

  // Load revisions and write an entry for each file in this directory.
  std::vector<Revision> revisions;
  for(Directory::const_iterator fi = dir.begin(); fi != dir.end(); ++fi)
    {
    std::string full = path + slash + fi->first;

    // Load two real or unknown revisions.
    revisions.clear();
    if(fi->second != PathUpdated)
      {
      // For local modifications the current rev is unknown and the
      // prior rev is the latest from cvs.
      revisions.push_back(this->Unknown);
      }
    this->LoadRevisions(full, branchFlag.c_str(), revisions);
    revisions.resize(2, this->Unknown);

    // Write the entry for this file with these revisions.
    File f(fi->second, &revisions[0], &revisions[1]);
    this->WriteXMLEntry(xml, path, fi->first, full, f);
    }
  xml << "\t</Directory>\n";
}

//----------------------------------------------------------------------------
bool cmCTestCVS::WriteXMLUpdates(std::ostream& xml)
{
  cmCTestLog(this->CTest, HANDLER_OUTPUT,
             "   Gathering version information (one . per updated file):\n"
             "    " << std::flush);

  for(std::map<cmStdString, Directory>::const_iterator
        di = this->Dirs.begin(); di != this->Dirs.end(); ++di)
    {
    this->WriteXMLDirectory(xml, di->first, di->second);
    }

  cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);

  return true;
}
