/*============================================================================
  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 "cmCTestBuildAndTestHandler.h"

#include "cmSystemTools.h"
#include "cmCTest.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
#include <cmsys/Process.h>
#include "cmCTestTestHandler.h"

//----------------------------------------------------------------------
cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
{
  this->BuildTwoConfig         = false;
  this->BuildNoClean           = false;
  this->BuildNoCMake           = false;
  this->Timeout = 0;
}

//----------------------------------------------------------------------
void cmCTestBuildAndTestHandler::Initialize()
{
  this->BuildTargets.erase(
    this->BuildTargets.begin(), this->BuildTargets.end());
  this->Superclass::Initialize();
}

//----------------------------------------------------------------------
const char* cmCTestBuildAndTestHandler::GetOutput()
{
  return this->Output.c_str();
}
//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::ProcessHandler()
{
  this->Output = "";
  std::string output;
  cmSystemTools::ResetErrorOccuredFlag();
  int retv = this->RunCMakeAndTest(&this->Output);
  cmSystemTools::ResetErrorOccuredFlag();
  return retv;
}

//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
  cmOStringStream &out, std::string &cmakeOutString, std::string &cwd,
  cmake *cm)
{
  unsigned int k;
  std::vector<std::string> args;
  args.push_back(this->CTest->GetCMakeExecutable());
  args.push_back(this->SourceDir);
  if(this->BuildGenerator.size())
    {
    std::string generator = "-G";
    generator += this->BuildGenerator;
    args.push_back(generator);
    }
  
  const char* config = 0;
  if ( this->CTest->GetConfigType().size() > 0 )
    {
    config = this->CTest->GetConfigType().c_str();
    }
#ifdef CMAKE_INTDIR
  if(!config)
    {
    config = CMAKE_INTDIR;
    }
#endif
  
  if ( config )
    {
    std::string btype
      = "-DCMAKE_BUILD_TYPE:STRING=" + std::string(config);
    args.push_back(btype);
    }

  for(k=0; k < this->BuildOptions.size(); ++k)
    {
    args.push_back(this->BuildOptions[k]);
    }
  if (cm->Run(args) != 0)
    {
    out << "Error: cmake execution failed\n";
    out << cmakeOutString << "\n";
    // return to the original directory
    cmSystemTools::ChangeDirectory(cwd.c_str());
    if(outstring)
      {
      *outstring = out.str();
      }
    else
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
      }
    return 1;
    }
  // do another config?
  if(this->BuildTwoConfig)
    {
    if (cm->Run(args) != 0)
      {
      out << "Error: cmake execution failed\n";
      out << cmakeOutString << "\n";
      // return to the original directory
      cmSystemTools::ChangeDirectory(cwd.c_str());
      if(outstring)
        {
        *outstring = out.str();
        }
      else
        {
        cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
        }
      return 1;
      }
    }
  out << "======== CMake output     ======\n";
  out << cmakeOutString;
  out << "======== End CMake output ======\n";
  return 0;
}

//----------------------------------------------------------------------
void CMakeMessageCallback(const char* m, const char*, bool&, void* s)
{
  std::string* out = (std::string*)s;
  *out += m;
  *out += "\n";
}

void CMakeProgressCallback(const char*msg, float , void * s)
{
  std::string* out = (std::string*)s;
  *out += msg;
  *out += "\n";
}

//----------------------------------------------------------------------
void CMakeStdoutCallback(const char* m, int len, void* s)
{
  std::string* out = (std::string*)s;
  out->append(m, len);
}
struct cmSetupOutputCaptureCleanup
{
  ~cmSetupOutputCaptureCleanup()
  {
    cmSystemTools::SetErrorCallback(0, 0);
    cmSystemTools::SetStdoutCallback(0, 0);
  }
};

//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
{
  unsigned int k;
  std::string cmakeOutString;
  cmSystemTools::SetErrorCallback(CMakeMessageCallback, &cmakeOutString);
  cmSystemTools::SetStdoutCallback(CMakeStdoutCallback, &cmakeOutString);
  // make sure SetStdoutCallback and SetErrorCallback are set to null
  // after this function exits so that they do not point at a destroyed
  // string cmakeOutString
  cmSetupOutputCaptureCleanup cleanup;
  static_cast<void>(cleanup);
  cmOStringStream out;

  // if the generator and make program are not specified then it is an error
  if (!this->BuildGenerator.size() || !this->BuildMakeProgram.size())
    {
    if(outstring)
      {
      *outstring =
        "--build-and-test requires that both the generator and makeprogram "
        "be provided using the --build-generator and --build-makeprogram "
        "command line options. ";
      }
    return 1;
    }

  if ( this->CTest->GetConfigType().size() == 0 &&
       this->ConfigSample.size())
    {
    // use the config sample to set the ConfigType
    std::string fullPath;
    std::string resultingConfig;
    std::vector<std::string> extraPaths;
    std::vector<std::string> failed;
    fullPath = 
      cmCTestTestHandler::FindExecutable(this->CTest, 
                                         this->ConfigSample.c_str(),
                                         resultingConfig,
                                         extraPaths,
                                         failed);
    if (fullPath.size() && resultingConfig.size())
      {
      this->CTest->SetConfigType(resultingConfig.c_str());
      }
    out << "Using config sample with results: "
        << fullPath << " and " << resultingConfig << std::endl;
    }
  
  // we need to honor the timeout specified, the timeout include cmake, build
  // and test time
  double clock_start = cmSystemTools::GetTime();

  // make sure the binary dir is there
  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  out << "Internal cmake changing into directory: "
    << this->BinaryDir << std::endl;
  if (!cmSystemTools::FileIsDirectory(this->BinaryDir.c_str()))
    {
    cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
    }
  cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());

  // should we cmake?
  cmake cm;
  cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString); 
  cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
      this->BuildGenerator.c_str()));

  if(!this->BuildNoCMake)
    {
    // do the cmake step, no timeout here since it is not a sub process
    if (this->RunCMake(outstring,out,cmakeOutString,cwd,&cm))
      {
      return 1;
      }
    }

  // do the build
  std::vector<std::string>::iterator tarIt;
  if ( this->BuildTargets.size() == 0 )
    {
    this->BuildTargets.push_back("");
    }
  for ( tarIt = this->BuildTargets.begin(); 
        tarIt != this->BuildTargets.end(); ++ tarIt )
    {
    double remainingTime = 0;
    if (this->Timeout > 0)
      {
      remainingTime = this->Timeout - cmSystemTools::GetTime() + clock_start;
      if (remainingTime <= 0)
        {
        if(outstring)
          {
          *outstring = "--build-and-test timeout exceeded. ";
          }
        return 1;
        }
      }
    std::string output;
    const char* config = 0;
    if ( this->CTest->GetConfigType().size() > 0 )
      {
      config = this->CTest->GetConfigType().c_str();
      }
#ifdef CMAKE_INTDIR
    if(!config)
      {
      config = CMAKE_INTDIR;
      }
#endif
    if(!config)
      {
      config = "Debug";
      }
    int retVal = cm.GetGlobalGenerator()->Build(
      this->SourceDir.c_str(), this->BinaryDir.c_str(),
      this->BuildProject.c_str(), tarIt->c_str(),
      &output, this->BuildMakeProgram.c_str(),
      config,
      !this->BuildNoClean, 
      false, remainingTime);
    out << output;
    // if the build failed then return
    if (retVal)
      {
      if(outstring)
        {
        *outstring =  out.str();
        }
      return 1;
      }
    }
  if(outstring)
    {
    *outstring =  out.str();
    }

  // if no test was specified then we are done
  if (!this->TestCommand.size())
    {
    return 0;
    }

  // now run the compiled test if we can find it
  // store the final location in fullPath
  std::string fullPath;
  std::string resultingConfig;
  std::vector<std::string> extraPaths;
  // if this->ExecutableDirectory is set try that as well
  if (this->ExecutableDirectory.size())
    {
    std::string tempPath = this->ExecutableDirectory;
    tempPath += "/";
    tempPath += this->TestCommand;
    extraPaths.push_back(tempPath);
    }
  std::vector<std::string> failed;
  fullPath = 
    cmCTestTestHandler::FindExecutable(this->CTest, 
                                       this->TestCommand.c_str(),
                                       resultingConfig,
                                       extraPaths,
                                       failed);
  
  if(!cmSystemTools::FileExists(fullPath.c_str()))
    {
    out << "Could not find path to executable, perhaps it was not built: "
      << this->TestCommand << "\n";
    out << "tried to find it in these places:\n";
    out << fullPath.c_str() << "\n";
    for(unsigned int i=0; i < failed.size(); ++i)
      {
      out << failed[i] << "\n";
      }
    if(outstring)
      {
      *outstring =  out.str();
      }
    else
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
      }
    // return to the original directory
    cmSystemTools::ChangeDirectory(cwd.c_str());
    return 1;
    }

  std::vector<const char*> testCommand;
  testCommand.push_back(fullPath.c_str());
  for(k=0; k < this->TestCommandArgs.size(); ++k)
    {
    testCommand.push_back(this->TestCommandArgs[k].c_str());
    }
  testCommand.push_back(0);
  std::string outs;
  int retval = 0;
  // run the test from the this->BuildRunDir if set
  if(this->BuildRunDir.size())
    {
    out << "Run test in directory: " << this->BuildRunDir << "\n";
    cmSystemTools::ChangeDirectory(this->BuildRunDir.c_str());
    }
  out << "Running test command: \"" << fullPath << "\"";
  for(k=0; k < this->TestCommandArgs.size(); ++k)
    {
    out << " \"" << this->TestCommandArgs[k] << "\"";
    }
  out << "\n";

  // how much time is remaining
  double remainingTime = 0;
  if (this->Timeout > 0)
    {
    remainingTime = this->Timeout - cmSystemTools::GetTime() + clock_start;
    if (remainingTime <= 0)
      {
      if(outstring)
        {
        *outstring = "--build-and-test timeout exceeded. ";
        }
      return 1;
      }
    }
  
  int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, 0, 
                                        remainingTime, 0);

  if(runTestRes != cmsysProcess_State_Exited || retval != 0)
    {
    out << "Test command failed: " << testCommand[0] << "\n";
    retval = 1;
    }

  out << outs << "\n";
  if(outstring)
    {
    *outstring = out.str();
    }
  else
    {
    cmCTestLog(this->CTest, OUTPUT, out.str() << std::endl);
    }
  return retval;
}

//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
  const std::string& currentArg, size_t& idx,
  const std::vector<std::string>& allArgs)
{
  // --build-and-test options
  if(currentArg.find("--build-and-test",0) == 0 && idx < allArgs.size() - 1)
    {
    if(idx+2 < allArgs.size())
      {
      idx++;
      this->SourceDir = allArgs[idx];
      idx++;
      this->BinaryDir = allArgs[idx];
      // dir must exist before CollapseFullPath is called
      cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
      this->BinaryDir
        = cmSystemTools::CollapseFullPath(this->BinaryDir.c_str());
      this->SourceDir
        = cmSystemTools::CollapseFullPath(this->SourceDir.c_str());
      }
    else
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
        "--build-and-test must have source and binary dir" << std::endl);
      return 0;
      }
    }
  if(currentArg.find("--build-target",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildTargets.push_back(allArgs[idx]);
    }
  if(currentArg.find("--build-nocmake",0) == 0)
    {
    this->BuildNoCMake = true;
    }
  if(currentArg.find("--build-run-dir",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildRunDir = allArgs[idx];
    }
  if(currentArg.find("--build-two-config",0) == 0)
    {
    this->BuildTwoConfig = true;
    }
  if(currentArg.find("--build-exe-dir",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->ExecutableDirectory = allArgs[idx];
    }
  if(currentArg.find("--test-timeout",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->Timeout = atof(allArgs[idx].c_str());
    }
  if(currentArg.find("--build-generator",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildGenerator = allArgs[idx];
    }
  if(currentArg.find("--build-project",0) == 0 && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildProject = allArgs[idx];
    }
  if(currentArg.find("--build-makeprogram",0) == 0 &&
    idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildMakeProgram = allArgs[idx];
    }
  if(currentArg.find("--build-config-sample",0) == 0 &&
    idx < allArgs.size() - 1)
    {
    idx++;
    this->ConfigSample = allArgs[idx];
    }
  if(currentArg.find("--build-noclean",0) == 0)
    {
    this->BuildNoClean = true;
    }
  if(currentArg.find("--build-options",0) == 0 && idx < allArgs.size() - 1)
    {
    ++idx;
    bool done = false;
    while(idx < allArgs.size() && !done)
      {
      this->BuildOptions.push_back(allArgs[idx]);
      if(idx+1 < allArgs.size()
         && (allArgs[idx+1] == "--build-target" ||
             allArgs[idx+1] == "--test-command"))
        {
        done = true;
        }
      else
        {
        ++idx;
        }
      }
    }
  if(currentArg.find("--test-command",0) == 0 && idx < allArgs.size() - 1)
    {
    ++idx;
    this->TestCommand = allArgs[idx];
    while(idx+1 < allArgs.size())
      {
      ++idx;
      this->TestCommandArgs.push_back(allArgs[idx]);
      }
    }
  return 1;
}

