/*============================================================================
  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 "cmExecuteProcessCommand.h"
#include "cmSystemTools.h"

#include <cmsys/Process.h>

#include <ctype.h> /* isspace */

static bool cmExecuteProcessCommandIsWhitespace(char c)
{
  return (isspace((int)c) || c == '\n' || c == '\r');
}

void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                    bool strip_trailing_whitespace);
void cmExecuteProcessCommandAppend(std::vector<char>& output,
                                   const char* data, int length);

// cmExecuteProcessCommand
bool cmExecuteProcessCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 1 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  std::vector< std::vector<const char*> > cmds;
  std::string arguments;
  bool doing_command = false;
  size_t command_index = 0;
  bool output_quiet = false;
  bool error_quiet = false;
  bool output_strip_trailing_whitespace = false;
  bool error_strip_trailing_whitespace = false;
  std::string timeout_string;
  std::string input_file;
  std::string output_file;
  std::string error_file;
  std::string output_variable;
  std::string error_variable;
  std::string result_variable;
  std::string working_directory;
  for(size_t i=0; i < args.size(); ++i)
    {
    if(args[i] == "COMMAND")
      {
      doing_command = true;
      command_index = cmds.size();
      cmds.push_back(std::vector<const char*>());
      }
    else if(args[i] == "OUTPUT_VARIABLE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        output_variable = args[i];
        }
      else
        {
        this->SetError(" called with no value for OUTPUT_VARIABLE.");
        return false;
        }
      }
    else if(args[i] == "ERROR_VARIABLE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        error_variable = args[i];
        }
      else
        {
        this->SetError(" called with no value for ERROR_VARIABLE.");
        return false;
        }
      }
    else if(args[i] == "RESULT_VARIABLE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        result_variable = args[i];
        }
      else
        {
        this->SetError(" called with no value for RESULT_VARIABLE.");
        return false;
        }
      }
    else if(args[i] == "WORKING_DIRECTORY")
      {
      doing_command = false;
      if(++i < args.size())
        {
        working_directory = args[i];
        }
      else
        {
        this->SetError(" called with no value for WORKING_DIRECTORY.");
        return false;
        }
      }
    else if(args[i] == "INPUT_FILE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        input_file = args[i];
        }
      else
        {
        this->SetError(" called with no value for INPUT_FILE.");
        return false;
        }
      }
    else if(args[i] == "OUTPUT_FILE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        output_file = args[i];
        }
      else
        {
        this->SetError(" called with no value for OUTPUT_FILE.");
        return false;
        }
      }
    else if(args[i] == "ERROR_FILE")
      {
      doing_command = false;
      if(++i < args.size())
        {
        error_file = args[i];
        }
      else
        {
        this->SetError(" called with no value for ERROR_FILE.");
        return false;
        }
      }
    else if(args[i] == "TIMEOUT")
      {
      doing_command = false;
      if(++i < args.size())
        {
        timeout_string = args[i];
        }
      else
        {
        this->SetError(" called with no value for TIMEOUT.");
        return false;
        }
      }
    else if(args[i] == "OUTPUT_QUIET")
      {
      doing_command = false;
      output_quiet = true;
      }
    else if(args[i] == "ERROR_QUIET")
      {
      doing_command = false;
      error_quiet = true;
      }
    else if(args[i] == "OUTPUT_STRIP_TRAILING_WHITESPACE")
      {
      doing_command = false;
      output_strip_trailing_whitespace = true;
      }
    else if(args[i] == "ERROR_STRIP_TRAILING_WHITESPACE")
      {
      doing_command = false;
      error_strip_trailing_whitespace = true;
      }
    else if(doing_command)
      {
      cmds[command_index].push_back(args[i].c_str());
      }
    else
      {
      cmOStringStream e;
      e << " given unknown argument \"" << args[i] << "\".";
      this->SetError(e.str().c_str());
      return false;
      }
    }

  if ( !this->Makefile->CanIWriteThisFile(output_file.c_str()) )
    {
    std::string e = "attempted to output into a file: " + output_file
      + " into a source directory.";
    this->SetError(e.c_str());
    cmSystemTools::SetFatalErrorOccured();
    return false;
    }

  // Check for commands given.
  if(cmds.empty())
    {
    this->SetError(" called with no COMMAND argument.");
    return false;
    }
  for(unsigned int i=0; i < cmds.size(); ++i)
    {
    if(cmds[i].empty())
      {
      this->SetError(" given COMMAND argument with no value.");
      return false;
      }
    else
      {
      // Add the null terminating pointer to the command argument list.
      cmds[i].push_back(0);
      }
    }

  // Parse the timeout string.
  double timeout = -1;
  if(!timeout_string.empty())
    {
    if(sscanf(timeout_string.c_str(), "%lg", &timeout) != 1)
      {
      this->SetError(" called with TIMEOUT value that could not be parsed.");
      return false;
      }
    }

  // Create a process instance.
  cmsysProcess* cp = cmsysProcess_New();

  // Set the command sequence.
  for(unsigned int i=0; i < cmds.size(); ++i)
    {
    cmsysProcess_AddCommand(cp, &*cmds[i].begin());
    }

  // Set the process working directory.
  if(!working_directory.empty())
    {
    cmsysProcess_SetWorkingDirectory(cp, working_directory.c_str());
    }

  // Always hide the process window.
  cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);

  // Check the output variables.
  bool merge_output = (output_variable == error_variable);
  if(error_variable.empty() && !error_quiet)
    {
    cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
    }
  if(!input_file.empty())
    {
    cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN, input_file.c_str());
    }
  if(!output_file.empty())
    {
    cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT,
                             output_file.c_str());
    }
  if(!error_file.empty())
    {
    cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
                             error_file.c_str());
    }

  // Set the timeout if any.
  if(timeout >= 0)
    {
    cmsysProcess_SetTimeout(cp, timeout);
    }

  // Start the process.
  cmsysProcess_Execute(cp);

  // Read the process output.
  std::vector<char> tempOutput;
  std::vector<char> tempError;
  int length;
  char* data;
  int p;
  while((p = cmsysProcess_WaitForData(cp, &data, &length, 0), p))
    {
    // Put the output in the right place.
    if((p == cmsysProcess_Pipe_STDOUT && !output_quiet) ||
       (p == cmsysProcess_Pipe_STDERR && !error_quiet && merge_output))
      {
      if(output_variable.empty())
        {
        cmSystemTools::Stdout(data, length);
        }
      else
        {
        cmExecuteProcessCommandAppend(tempOutput, data, length);
        }
      }
    else if(p == cmsysProcess_Pipe_STDERR && !error_quiet)
      {
      if(!error_variable.empty())
        {
        cmExecuteProcessCommandAppend(tempError, data, length);
        }
      }
    }

  // All output has been read.  Wait for the process to exit.
  cmsysProcess_WaitForExit(cp, 0);

  // Fix the text in the output strings.
  cmExecuteProcessCommandFixText(tempOutput,
                                 output_strip_trailing_whitespace);
  cmExecuteProcessCommandFixText(tempError,
                                 error_strip_trailing_whitespace);

  // Store the output obtained.
  if(!output_variable.empty() && tempOutput.size())
    {
    this->Makefile->AddDefinition(output_variable.c_str(),
                                  &*tempOutput.begin());
    }
  if(!merge_output && !error_variable.empty() && tempError.size())
    {
    this->Makefile->AddDefinition(error_variable.c_str(),
                                  &*tempError.begin());
    }

  // Store the result of running the process.
  if(!result_variable.empty())
    {
    switch(cmsysProcess_GetState(cp))
      {
      case cmsysProcess_State_Exited:
        {
        int v = cmsysProcess_GetExitValue(cp);
        char buf[100];
        sprintf(buf, "%d", v);
        this->Makefile->AddDefinition(result_variable.c_str(), buf);
        }
        break;
      case cmsysProcess_State_Exception:
        this->Makefile->AddDefinition(result_variable.c_str(),
                                  cmsysProcess_GetExceptionString(cp));
        break;
      case cmsysProcess_State_Error:
        this->Makefile->AddDefinition(result_variable.c_str(),
                                  cmsysProcess_GetErrorString(cp));
        break;
      case cmsysProcess_State_Expired:
        this->Makefile->AddDefinition(result_variable.c_str(),
                                  "Process terminated due to timeout");
        break;
      }
    }

  // Delete the process instance.
  cmsysProcess_Delete(cp);

  return true;
}

//----------------------------------------------------------------------------
void cmExecuteProcessCommandFixText(std::vector<char>& output,
                                    bool strip_trailing_whitespace)
{
  // Remove \0 characters and the \r part of \r\n pairs.
  unsigned int in_index = 0;
  unsigned int out_index = 0;
  while(in_index < output.size())
    {
    char c = output[in_index++];
    if((c != '\r' || !(in_index < output.size() && output[in_index] == '\n'))
       && c != '\0')
      {
      output[out_index++] = c;
      }
    }

  // Remove trailing whitespace if requested.
  if(strip_trailing_whitespace)
    {
    while(out_index > 0 &&
          cmExecuteProcessCommandIsWhitespace(output[out_index-1]))
      {
      --out_index;
      }
    }

  // Shrink the vector to the size needed.
  output.resize(out_index);

  // Put a terminator on the text string.
  output.push_back('\0');
}

//----------------------------------------------------------------------------
void cmExecuteProcessCommandAppend(std::vector<char>& output,
                                   const char* data, int length)
{
#if defined(__APPLE__)
  // HACK on Apple to work around bug with inserting at the
  // end of an empty vector.  This resulted in random failures
  // that were hard to reproduce.
  if(output.empty() && length > 0)
    {
    output.push_back(data[0]);
    ++data;
    --length;
    }
#endif
  output.insert(output.end(), data, data+length);
}
