/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmCTestBZR.h"

#include <cstdlib>
#include <list>
#include <map>
#include <ostream>
#include <vector>

#include <cmext/algorithm>

#include "cmsys/RegularExpression.hxx"

#include "cm_expat.h"

#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"

extern "C" int cmBZRXMLParserUnknownEncodingHandler(void* /*unused*/,
                                                    const XML_Char* name,
                                                    XML_Encoding* info)
{
  static const int latin1[] = {
    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
    0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
    0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A,
    0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
    0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C,
    0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
    0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E,
    0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
    0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
    0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
    0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062,
    0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B,
    0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
    0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D,
    0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020,
    0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F,
    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC,
    0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, 0x00A0, 0x00A1,
    0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA,
    0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3,
    0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC,
    0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5,
    0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE,
    0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
    0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0,
    0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9,
    0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2,
    0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB,
    0x00FC, 0x00FD, 0x00FE, 0x00FF
  };

  // The BZR xml output plugin can use some encodings that are not
  // recognized by expat.  This will lead to an error, e.g. "Error
  // parsing bzr log xml: unknown encoding", the following is a
  // workaround for these unknown encodings.
  if (name == std::string("ascii") || name == std::string("cp1252") ||
      name == std::string("ANSI_X3.4-1968")) {
    for (unsigned int i = 0; i < 256; ++i) {
      info->map[i] = latin1[i];
    }
    return 1;
  }

  return 0;
}

cmCTestBZR::cmCTestBZR(cmCTest* ct, std::ostream& log)
  : cmCTestGlobalVC(ct, log)
{
  this->PriorRev = this->Unknown;
  // Even though it is specified in the documentation, with bzr 1.13
  // BZR_PROGRESS_BAR has no effect. In the future this bug might be fixed.
  // Since it doesn't hurt, we specify this environment variable.
  cmSystemTools::PutEnv("BZR_PROGRESS_BAR=none");
}

cmCTestBZR::~cmCTestBZR() = default;

class cmCTestBZR::InfoParser : public cmCTestVC::LineParser
{
public:
  InfoParser(cmCTestBZR* bzr, const char* prefix)
    : BZR(bzr)
    , CheckOutFound(false)
  {
    this->SetLog(&bzr->Log, prefix);
    this->RegexCheckOut.compile("checkout of branch: *([^\t\r\n]+)$");
    this->RegexParent.compile("parent branch: *([^\t\r\n]+)$");
  }

private:
  cmCTestBZR* BZR;
  bool CheckOutFound;
  cmsys::RegularExpression RegexCheckOut;
  cmsys::RegularExpression RegexParent;
  bool ProcessLine() override
  {
    if (this->RegexCheckOut.find(this->Line)) {
      this->BZR->URL = this->RegexCheckOut.match(1);
      CheckOutFound = true;
    } else if (!CheckOutFound && this->RegexParent.find(this->Line)) {
      this->BZR->URL = this->RegexParent.match(1);
    }
    return true;
  }
};

class cmCTestBZR::RevnoParser : public cmCTestVC::LineParser
{
public:
  RevnoParser(cmCTestBZR* bzr, const char* prefix, std::string& rev)
    : Rev(rev)
  {
    this->SetLog(&bzr->Log, prefix);
    this->RegexRevno.compile("^([0-9]+)$");
  }

private:
  std::string& Rev;
  cmsys::RegularExpression RegexRevno;
  bool ProcessLine() override
  {
    if (this->RegexRevno.find(this->Line)) {
      this->Rev = this->RegexRevno.match(1);
    }
    return true;
  }
};

std::string cmCTestBZR::LoadInfo()
{
  // Run "bzr info" to get the repository info from the work tree.
  const char* bzr = this->CommandLineTool.c_str();
  const char* bzr_info[] = { bzr, "info", nullptr };
  InfoParser iout(this, "info-out> ");
  OutputLogger ierr(this->Log, "info-err> ");
  this->RunChild(bzr_info, &iout, &ierr);

  // Run "bzr revno" to get the repository revision number from the work tree.
  const char* bzr_revno[] = { bzr, "revno", nullptr };
  std::string rev;
  RevnoParser rout(this, "revno-out> ", rev);
  OutputLogger rerr(this->Log, "revno-err> ");
  this->RunChild(bzr_revno, &rout, &rerr);

  return rev;
}

bool cmCTestBZR::NoteOldRevision()
{
  this->OldRevision = this->LoadInfo();
  this->Log << "Revision before update: " << this->OldRevision << "\n";
  cmCTestLog(this->CTest, HANDLER_OUTPUT,
             "   Old revision of repository is: " << this->OldRevision
                                                  << "\n");
  this->PriorRev.Rev = this->OldRevision;
  return true;
}

bool cmCTestBZR::NoteNewRevision()
{
  this->NewRevision = this->LoadInfo();
  this->Log << "Revision after update: " << this->NewRevision << "\n";
  cmCTestLog(this->CTest, HANDLER_OUTPUT,
             "   New revision of repository is: " << this->NewRevision
                                                  << "\n");
  this->Log << "URL = " << this->URL << "\n";
  return true;
}

class cmCTestBZR::LogParser
  : public cmCTestVC::OutputLogger
  , private cmXMLParser
{
public:
  LogParser(cmCTestBZR* bzr, const char* prefix)
    : OutputLogger(bzr->Log, prefix)
    , BZR(bzr)
    , EmailRegex("(.*) <([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+)>")
  {
    this->InitializeParser();
  }
  ~LogParser() override { this->CleanupParser(); }

  int InitializeParser() override
  {
    int res = cmXMLParser::InitializeParser();
    if (res) {
      XML_SetUnknownEncodingHandler(static_cast<XML_Parser>(this->Parser),
                                    cmBZRXMLParserUnknownEncodingHandler,
                                    nullptr);
    }
    return res;
  }

private:
  cmCTestBZR* BZR;

  using Revision = cmCTestBZR::Revision;
  using Change = cmCTestBZR::Change;
  Revision Rev;
  std::vector<Change> Changes;
  Change CurChange;
  std::vector<char> CData;

  cmsys::RegularExpression EmailRegex;

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

  void StartElement(const std::string& name, const char** /*atts*/) override
  {
    this->CData.clear();
    if (name == "log") {
      this->Rev = Revision();
      this->Changes.clear();
    }
    // affected-files can contain blocks of
    // modified, unknown, renamed, kind-changed, removed, conflicts, added
    else if (name == "modified" || name == "renamed" ||
             name == "kind-changed") {
      this->CurChange = Change();
      this->CurChange.Action = 'M';
    } else if (name == "added") {
      this->CurChange = Change();
      this->CurChange = 'A';
    } else if (name == "removed") {
      this->CurChange = Change();
      this->CurChange = 'D';
    } else if (name == "unknown" || name == "conflicts") {
      // Should not happen here
      this->CurChange = Change();
    }
  }

  void CharacterDataHandler(const char* data, int length) override
  {
    cm::append(this->CData, data, data + length);
  }

  void EndElement(const std::string& name) override
  {
    if (name == "log") {
      this->BZR->DoRevision(this->Rev, this->Changes);
    } else if (!this->CData.empty() &&
               (name == "file" || name == "directory")) {
      this->CurChange.Path.assign(&this->CData[0], this->CData.size());
      cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
      this->Changes.push_back(this->CurChange);
    } else if (!this->CData.empty() && name == "symlink") {
      // symlinks have an arobase at the end in the log
      this->CurChange.Path.assign(&this->CData[0], this->CData.size() - 1);
      cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
      this->Changes.push_back(this->CurChange);
    } else if (!this->CData.empty() && name == "committer") {
      this->Rev.Author.assign(&this->CData[0], this->CData.size());
      if (this->EmailRegex.find(this->Rev.Author)) {
        this->Rev.Author = this->EmailRegex.match(1);
        this->Rev.EMail = this->EmailRegex.match(2);
      }
    } else if (!this->CData.empty() && name == "timestamp") {
      this->Rev.Date.assign(&this->CData[0], this->CData.size());
    } else if (!this->CData.empty() && name == "message") {
      this->Rev.Log.assign(&this->CData[0], this->CData.size());
    } else if (!this->CData.empty() && name == "revno") {
      this->Rev.Rev.assign(&this->CData[0], this->CData.size());
    }
    this->CData.clear();
  }

  void ReportError(int /*line*/, int /*column*/, const char* msg) override
  {
    this->BZR->Log << "Error parsing bzr log xml: " << msg << "\n";
  }
};

class cmCTestBZR::UpdateParser : public cmCTestVC::LineParser
{
public:
  UpdateParser(cmCTestBZR* bzr, const char* prefix)
    : BZR(bzr)
  {
    this->SetLog(&bzr->Log, prefix);
    this->RegexUpdate.compile("^([-+R?XCP ])([NDKM ])([* ]) +(.+)$");
  }

private:
  cmCTestBZR* BZR;
  cmsys::RegularExpression RegexUpdate;

  bool ProcessChunk(const char* first, int length) override
  {
    bool last_is_new_line = (*first == '\r' || *first == '\n');

    const char* const last = first + length;
    for (const char* c = first; c != last; ++c) {
      if (*c == '\r' || *c == '\n') {
        if (!last_is_new_line) {
          // Log this line.
          if (this->Log && this->Prefix) {
            *this->Log << this->Prefix << this->Line << "\n";
          }

          // Hand this line to the subclass implementation.
          if (!this->ProcessLine()) {
            this->Line.clear();
            return false;
          }

          this->Line.clear();
          last_is_new_line = true;
        }
      } else {
        // Append this character to the line under construction.
        this->Line.append(1, *c);
        last_is_new_line = false;
      }
    }
    return true;
  }

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

  void DoPath(char c0, char c1, char c2, std::string path)
  {
    if (path.empty()) {
      return;
    }
    cmSystemTools::ConvertToUnixSlashes(path);

    const std::string dir = cmSystemTools::GetFilenamePath(path);
    const std::string name = cmSystemTools::GetFilenameName(path);

    if (c0 == 'C') {
      this->BZR->Dirs[dir][name].Status = PathConflicting;
      return;
    }

    if (c1 == 'M' || c1 == 'K' || c1 == 'N' || c1 == 'D' || c2 == '*') {
      this->BZR->Dirs[dir][name].Status = PathUpdated;
      return;
    }
  }
};

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

  // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)

  // Use "bzr pull" to update the working tree.
  std::vector<char const*> bzr_update;
  bzr_update.push_back(this->CommandLineTool.c_str());
  bzr_update.push_back("pull");

  for (std::string const& arg : args) {
    bzr_update.push_back(arg.c_str());
  }

  bzr_update.push_back(this->URL.c_str());

  bzr_update.push_back(nullptr);

  // For some reason bzr uses stderr to display the update status.
  OutputLogger out(this->Log, "pull-out> ");
  UpdateParser err(this, "pull-err> ");
  return this->RunUpdateCommand(&bzr_update[0], &out, &err);
}

bool cmCTestBZR::LoadRevisions()
{
  cmCTestLog(this->CTest, HANDLER_OUTPUT,
             "   Gathering version information (one . per revision):\n"
             "    "
               << std::flush);

  // We are interested in every revision included in the update.
  this->Revisions.clear();
  std::string revs;
  if (atoi(this->OldRevision.c_str()) <= atoi(this->NewRevision.c_str())) {
    // DoRevision takes care of discarding the information about OldRevision
    revs = this->OldRevision + ".." + this->NewRevision;
  } else {
    return true;
  }

  // Run "bzr log" to get all global revisions of interest.
  const char* bzr = this->CommandLineTool.c_str();
  const char* bzr_log[] = {
    bzr, "log", "-v", "-r", revs.c_str(), "--xml", this->URL.c_str(), nullptr
  };
  {
    LogParser out(this, "log-out> ");
    OutputLogger err(this->Log, "log-err> ");
    this->RunChild(bzr_log, &out, &err);
  }
  cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
  return true;
}

class cmCTestBZR::StatusParser : public cmCTestVC::LineParser
{
public:
  StatusParser(cmCTestBZR* bzr, const char* prefix)
    : BZR(bzr)
  {
    this->SetLog(&bzr->Log, prefix);
    this->RegexStatus.compile("^([-+R?XCP ])([NDKM ])([* ]) +(.+)$");
  }

private:
  cmCTestBZR* BZR;
  cmsys::RegularExpression RegexStatus;
  bool ProcessLine() override
  {
    if (this->RegexStatus.find(this->Line)) {
      this->DoPath(this->RegexStatus.match(1)[0],
                   this->RegexStatus.match(2)[0],
                   this->RegexStatus.match(3)[0], this->RegexStatus.match(4));
    }
    return true;
  }

  void DoPath(char c0, char c1, char c2, std::string path)
  {
    if (path.empty()) {
      return;
    }
    cmSystemTools::ConvertToUnixSlashes(path);

    if (c0 == 'C') {
      this->BZR->DoModification(PathConflicting, path);
      return;
    }

    if (c0 == '+' || c0 == 'R' || c0 == 'P' || c1 == 'M' || c1 == 'K' ||
        c1 == 'N' || c1 == 'D' || c2 == '*') {
      this->BZR->DoModification(PathModified, path);
      return;
    }
  }
};

bool cmCTestBZR::LoadModifications()
{
  // Run "bzr status" which reports local modifications.
  const char* bzr = this->CommandLineTool.c_str();
  const char* bzr_status[] = { bzr, "status", "-SV", nullptr };
  StatusParser out(this, "status-out> ");
  OutputLogger err(this->Log, "status-err> ");
  this->RunChild(bzr_status, &out, &err);
  return true;
}
