/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  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 <cmProcess.h>

#include <cmSystemTools.h>

cmProcess::cmProcess()
{
  this->Process = 0;
  this->Timeout = 0;
  this->TotalTime = 0;
  this->ExitValue = 0;
  this->Id = 0;
  this->StartTime = 0;
}

cmProcess::~cmProcess()
{
  cmsysProcess_Delete(this->Process);
}
void cmProcess::SetCommand(const char* command)
{
  this->Command = command;
}

void cmProcess::SetCommandArguments(std::vector<std::string> const& args)
{
  this->Arguments = args;
}

bool cmProcess::StartProcess()
{
  if (this->Command.empty()) {
    return false;
  }
  this->StartTime = cmSystemTools::GetTime();
  this->ProcessArgs.clear();
  // put the command as arg0
  this->ProcessArgs.push_back(this->Command.c_str());
  // now put the command arguments in
  for (std::vector<std::string>::iterator i = this->Arguments.begin();
       i != this->Arguments.end(); ++i) {
    this->ProcessArgs.push_back(i->c_str());
  }
  this->ProcessArgs.push_back(0); // null terminate the list
  this->Process = cmsysProcess_New();
  cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin());
  if (!this->WorkingDirectory.empty()) {
    cmsysProcess_SetWorkingDirectory(this->Process,
                                     this->WorkingDirectory.c_str());
  }
  cmsysProcess_SetTimeout(this->Process, this->Timeout);
  cmsysProcess_SetOption(this->Process, cmsysProcess_Option_MergeOutput, 1);
  cmsysProcess_Execute(this->Process);
  return (cmsysProcess_GetState(this->Process) ==
          cmsysProcess_State_Executing);
}

bool cmProcess::Buffer::GetLine(std::string& line)
{
  // Scan for the next newline.
  for (size_type sz = this->size(); this->Last != sz; ++this->Last) {
    if ((*this)[this->Last] == '\n' || (*this)[this->Last] == '\0') {
      // Extract the range first..last as a line.
      const char* text = &*this->begin() + this->First;
      size_type length = this->Last - this->First;
      while (length && text[length - 1] == '\r') {
        length--;
      }
      line.assign(text, length);

      // Start a new range for the next line.
      ++this->Last;
      this->First = Last;

      // Return the line extracted.
      return true;
    }
  }

  // Available data have been exhausted without a newline.
  if (this->First != 0) {
    // Move the partial line to the beginning of the buffer.
    this->erase(this->begin(), this->begin() + this->First);
    this->First = 0;
    this->Last = this->size();
  }
  return false;
}

bool cmProcess::Buffer::GetLast(std::string& line)
{
  // Return the partial last line, if any.
  if (!this->empty()) {
    line.assign(&*this->begin(), this->size());
    this->First = this->Last = 0;
    this->clear();
    return true;
  }
  return false;
}

int cmProcess::GetNextOutputLine(std::string& line, double timeout)
{
  for (;;) {
    // Look for lines already buffered.
    if (this->Output.GetLine(line)) {
      return cmsysProcess_Pipe_STDOUT;
    }

    // Check for more data from the process.
    char* data;
    int length;
    int p = cmsysProcess_WaitForData(this->Process, &data, &length, &timeout);
    if (p == cmsysProcess_Pipe_Timeout) {
      return cmsysProcess_Pipe_Timeout;
    } else if (p == cmsysProcess_Pipe_STDOUT) {
      this->Output.insert(this->Output.end(), data, data + length);
    } else // p == cmsysProcess_Pipe_None
    {
      // The process will provide no more data.
      break;
    }
  }

  // Look for partial last lines.
  if (this->Output.GetLast(line)) {
    return cmsysProcess_Pipe_STDOUT;
  }

  // No more data.  Wait for process exit.
  if (!cmsysProcess_WaitForExit(this->Process, &timeout)) {
    return cmsysProcess_Pipe_Timeout;
  }

  // Record exit information.
  this->ExitValue = cmsysProcess_GetExitValue(this->Process);
  this->TotalTime = cmSystemTools::GetTime() - this->StartTime;
  // Because of a processor clock scew the runtime may become slightly
  // negative. If someone changed the system clock while the process was
  // running this may be even more. Make sure not to report a negative
  // duration here.
  if (this->TotalTime <= 0.0) {
    this->TotalTime = 0.0;
  }
  //  std::cerr << "Time to run: " << this->TotalTime << "\n";
  return cmsysProcess_Pipe_None;
}

// return the process status
int cmProcess::GetProcessStatus()
{
  if (!this->Process) {
    return cmsysProcess_State_Exited;
  }
  return cmsysProcess_GetState(this->Process);
}

int cmProcess::ReportStatus()
{
  int result = 1;
  switch (cmsysProcess_GetState(this->Process)) {
    case cmsysProcess_State_Starting: {
      std::cerr << "cmProcess: Never started " << this->Command
                << " process.\n";
    } break;
    case cmsysProcess_State_Error: {
      std::cerr << "cmProcess: Error executing " << this->Command
                << " process: " << cmsysProcess_GetErrorString(this->Process)
                << "\n";
    } break;
    case cmsysProcess_State_Exception: {
      std::cerr << "cmProcess: " << this->Command
                << " process exited with an exception: ";
      switch (cmsysProcess_GetExitException(this->Process)) {
        case cmsysProcess_Exception_None: {
          std::cerr << "None";
        } break;
        case cmsysProcess_Exception_Fault: {
          std::cerr << "Segmentation fault";
        } break;
        case cmsysProcess_Exception_Illegal: {
          std::cerr << "Illegal instruction";
        } break;
        case cmsysProcess_Exception_Interrupt: {
          std::cerr << "Interrupted by user";
        } break;
        case cmsysProcess_Exception_Numerical: {
          std::cerr << "Numerical exception";
        } break;
        case cmsysProcess_Exception_Other: {
          std::cerr << "Unknown";
        } break;
      }
      std::cerr << "\n";
    } break;
    case cmsysProcess_State_Executing: {
      std::cerr << "cmProcess: Never terminated " << this->Command
                << " process.\n";
    } break;
    case cmsysProcess_State_Exited: {
      result = cmsysProcess_GetExitValue(this->Process);
      std::cerr << "cmProcess: " << this->Command
                << " process exited with code " << result << "\n";
    } break;
    case cmsysProcess_State_Expired: {
      std::cerr << "cmProcess: killed " << this->Command
                << " process due to timeout.\n";
    } break;
    case cmsysProcess_State_Killed: {
      std::cerr << "cmProcess: killed " << this->Command << " process.\n";
    } break;
  }
  return result;
}

void cmProcess::ChangeTimeout(double t)
{
  this->Timeout = t;
  cmsysProcess_SetTimeout(this->Process, this->Timeout);
}

void cmProcess::ResetStartTime()
{
  cmsysProcess_ResetStartTime(this->Process);
}

int cmProcess::GetExitException()
{
  return cmsysProcess_GetExitException(this->Process);
}
