/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices 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);
}
