/*============================================================================
  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
      {
      std::ostringstream 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 = false;
  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())
    {
    if (error_file == output_file)
      {
      merge_output = true;
      }
    else
      {
      cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
                               error_file.c_str());
      }
    }
  if (!output_variable.empty() && output_variable == error_variable)
    {
    merge_output = true;
    }
  if (merge_output)
    {
    cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
    }

  // 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)
      {
      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.empty())
    {
    this->Makefile->AddDefinition(output_variable,
                                  &*tempOutput.begin());
    }
  if(!merge_output && !error_variable.empty() && !tempError.empty())
    {
    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);
}
