/*============================================================================
  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());
      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);
    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(!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())
        {
        cmSystemTools::Stderr(data, length);
        }
      else
        {
        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,
                                  &*tempOutput.begin());
    }
  if(!merge_output && !error_variable.empty() && tempError.size())
    {
    this->Makefile->AddDefinition(error_variable,
                                  &*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, buf);
        }
        break;
      case cmsysProcess_State_Exception:
        this->Makefile->AddDefinition(result_variable,
                                  cmsysProcess_GetExceptionString(cp));
        break;
      case cmsysProcess_State_Error:
        this->Makefile->AddDefinition(result_variable,
                                  cmsysProcess_GetErrorString(cp));
        break;
      case cmsysProcess_State_Expired:
        this->Makefile->AddDefinition(result_variable,
                                  "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);
}
