/* 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 <cm3p/expat.h>

#include "cmsys/RegularExpression.hxx"

#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;
}
