/*============================================================================
  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>
#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(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<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;
}
