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

#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.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<std::string> 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<std::string>::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;
  cmsys::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(cmXMLWriter& xml,
                                   std::string const& path,
                                   Directory const& dir)
{
  const char* slash = path.empty()? "":"/";
  xml.StartElement("Directory");
  xml.Element("Name", path);

  // 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.EndElement(); // Directory
}

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

  for(std::map<std::string, 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;
}
