/*============================================================================
  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"
#include "cmCacheManager.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(cmSystemTools::GetCMakeCommand());
  args.push_back(this->SourceDir);
  if(this->BuildGenerator.size())
    {
    std::string generator = "-G";
    generator += this->BuildGenerator;
    args.push_back(generator);
    }
  if(this->BuildGeneratorToolset.size())
    {
    std::string toolset = "-T";
    toolset += this->BuildGeneratorToolset;
    args.push_back(toolset);
    }

  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())
    {
    if(outstring)
      {
      *outstring =
        "--build-and-test requires that the generator "
        "be provided using the --build-generator "
        "command line option. ";
      }
    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);

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

    // Load the cache to make CMAKE_MAKE_PROGRAM available.
    cm.GetCacheManager()->LoadCache(this->BinaryDir.c_str());
    }
  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.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 == "--build-generator" && idx < allArgs.size() - 1)
    {
    idx++;
    this->BuildGenerator = 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;
}

