/*============================================================================
  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.clear();
  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,
  std::ostringstream &out, std::string &cmakeOutString, std::string &cwd,
  cmake *cm)
{
  unsigned int k;
  std::vector<std::string> args;
  args.push_back(cmSystemTools::GetCMakeCommand());
  args.push_back(this->SourceDir);
  if(!this->BuildGenerator.empty())
    {
    std::string generator = "-G";
    generator += this->BuildGenerator;
    args.push_back(generator);
    }
  if(!this->BuildGeneratorPlatform.empty())
    {
    std::string platform = "-A";
    platform += this->BuildGeneratorPlatform;
    args.push_back(platform);
    }
  if(!this->BuildGeneratorToolset.empty())
    {
    std::string toolset = "-T";
    toolset += this->BuildGeneratorToolset;
    args.push_back(toolset);
    }

  const char* config = 0;
  if (!this->CTest->GetConfigType().empty())
    {
    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);
    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);
      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 CMakeOutputCallback(const char* m, size_t len, void* s)
{
  std::string* out = (std::string*)s;
  out->append(m, len);
}

//----------------------------------------------------------------------
class cmCTestBuildAndTestCaptureRAII
{
  cmake& CM;
public:
  cmCTestBuildAndTestCaptureRAII(cmake& cm, std::string& s): CM(cm)
    {
    cmSystemTools::SetMessageCallback(CMakeMessageCallback, &s);
    cmSystemTools::SetStdoutCallback(CMakeOutputCallback, &s);
    cmSystemTools::SetStderrCallback(CMakeOutputCallback, &s);
    this->CM.SetProgressCallback(CMakeProgressCallback, &s);
    }
  ~cmCTestBuildAndTestCaptureRAII()
    {
    this->CM.SetProgressCallback(0, 0);
    cmSystemTools::SetStderrCallback(0, 0);
    cmSystemTools::SetStdoutCallback(0, 0);
    cmSystemTools::SetMessageCallback(0, 0);
    }
};

//----------------------------------------------------------------------
int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
{
  // if the generator and make program are not specified then it is an error
  if (this->BuildGenerator.empty())
    {
    if(outstring)
      {
      *outstring =
        "--build-and-test requires that the generator "
        "be provided using the --build-generator "
        "command line option. ";
      }
    return 1;
    }

  cmake cm;
  cm.SetHomeDirectory("");
  cm.SetHomeOutputDirectory("");
  std::string cmakeOutString;
  cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString);
  static_cast<void>(captureRAII);
  std::ostringstream out;

  if ( this->CTest->GetConfigType().empty() &&
       !this->ConfigSample.empty())
    {
    // 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.empty() && !resultingConfig.empty())
      {
      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))
    {
    cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
    }
  cmSystemTools::ChangeDirectory(this->BinaryDir);

  if(this->BuildNoCMake)
    {
    // Make the generator available for the Build call below.
    cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
                            this->BuildGenerator));
    cm.SetGeneratorPlatform(this->BuildGeneratorPlatform);
    cm.SetGeneratorToolset(this->BuildGeneratorToolset);

    // Load the cache to make CMAKE_MAKE_PROGRAM available.
    cm.LoadCache(this->BinaryDir);
    }
  else
    {
    // 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.empty())
    {
    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().empty())
      {
      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, this->BinaryDir,
      this->BuildProject, *tarIt,
      output, this->BuildMakeProgram,
      config,
      !this->BuildNoClean,
      false, 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.empty())
    {
    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.empty())
    {
    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);
    return 1;
    }

  std::vector<const char*> testCommand;
  testCommand.push_back(fullPath.c_str());
  for(size_t 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.empty())
    {
    out << "Run test in directory: " << this->BuildRunDir << "\n";
    cmSystemTools::ChangeDirectory(this->BuildRunDir);
    }
  out << "Running test command: \"" << fullPath << "\"";
  for(size_t 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);
      this->SourceDir
        = cmSystemTools::CollapseFullPath(this->SourceDir);
      }
    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 == "--build-generator" && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildGenerator = allArgs[idx];
    }
  if(currentArg == "--build-generator-platform" &&
     idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildGeneratorPlatform = allArgs[idx];
    }
  if(currentArg == "--build-generator-toolset" &&
     idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildGeneratorToolset = 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)
    {
    while(idx+1 < allArgs.size() &&
          allArgs[idx+1] != "--build-target" &&
          allArgs[idx+1] != "--test-command")
      {
      ++idx;
      this->BuildOptions.push_back(allArgs[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;
}

