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

#include "cmsys/Process.h"
#include <ostream>

void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
                                OutputParser* err, Encoding encoding)
{
  cmsysProcess_Execute(cp);
  char* data = nullptr;
  int length = 0;
  int p;
  cmProcessOutput processOutput(encoding);
  std::string strdata;
  while ((out || err) &&
         (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) {
    if (out && p == cmsysProcess_Pipe_STDOUT) {
      processOutput.DecodeText(data, length, strdata, 1);
      if (!out->Process(strdata.c_str(), int(strdata.size()))) {
        out = nullptr;
      }
    } else if (err && p == cmsysProcess_Pipe_STDERR) {
      processOutput.DecodeText(data, length, strdata, 2);
      if (!err->Process(strdata.c_str(), int(strdata.size()))) {
        err = nullptr;
      }
    }
  }
  if (out) {
    processOutput.DecodeText(std::string(), strdata, 1);
    if (!strdata.empty()) {
      out->Process(strdata.c_str(), int(strdata.size()));
    }
  }
  if (err) {
    processOutput.DecodeText(std::string(), strdata, 2);
    if (!strdata.empty()) {
      err->Process(strdata.c_str(), int(strdata.size()));
    }
  }
  cmsysProcess_WaitForExit(cp, nullptr);
}

cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR)
  : Log(nullptr)
  , Prefix(nullptr)
  , Separator(sep)
  , LineEnd('\0')
  , IgnoreCR(ignoreCR)
{
}

void cmProcessTools::LineParser::SetLog(std::ostream* log, const char* prefix)
{
  this->Log = log;
  this->Prefix = prefix ? prefix : "";
}

bool cmProcessTools::LineParser::ProcessChunk(const char* first, int length)
{
  const char* last = first + length;
  for (const char* c = first; c != last; ++c) {
    if (*c == this->Separator || *c == '\0') {
      this->LineEnd = *c;

      // 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();
    } else if (*c != '\r' || !this->IgnoreCR) {
      // Append this character to the line under construction.
      this->Line.append(1, *c);
    }
  }
  return true;
}
