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

#include "cmCTest.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmCTestVC.h"
#include "cmGeneratedFileStream.h"

cmCTestStartCommand::cmCTestStartCommand()
{
  this->CreateNewTag = true;
}

bool cmCTestStartCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if (args.size() < 1)
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  size_t cnt = 0;
  const char* smodel = args[cnt].c_str();
  const char* src_dir = 0;
  const char* bld_dir = 0;

  cnt++;

  this->CTest->SetSpecificTrack(0);
  if ( cnt < args.size() -1 )
    {
    if ( args[cnt] == "TRACK" )
      {
      cnt ++;
      this->CTest->SetSpecificTrack(args[cnt].c_str());
      cnt ++;
      }
    }

  if (cnt < args.size())
    {
    if (args[cnt] == "APPEND")
      {
      cnt ++;
      this->CreateNewTag = false;
      }
    }

  if ( cnt < args.size() )
    {
    src_dir = args[cnt].c_str();
    cnt ++;
    if ( cnt < args.size() )
      {
      bld_dir = args[cnt].c_str();
      }
    }
  if ( !src_dir )
    {
    src_dir = this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY");
    }
  if ( !bld_dir)
    {
    bld_dir = this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY");
    }
  if ( !src_dir )
    {
    this->SetError("source directory not specified. Specify source directory "
      "as an argument or set CTEST_SOURCE_DIRECTORY");
    return false;
    }
  if ( !bld_dir)
    {
    this->SetError("binary directory not specified. Specify binary directory "
      "as an argument or set CTEST_BINARY_DIRECTORY");
    return false;
    }

  cmSystemTools::AddKeepPath(src_dir);
  cmSystemTools::AddKeepPath(bld_dir);

  this->CTest->EmptyCTestConfiguration();

  std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir);
  std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir);
  this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str());
  this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str());

  cmCTestLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model "
    << smodel << std::endl
    << "   Source directory: " << src_dir << std::endl
    << "   Build directory: " << bld_dir << std::endl);
  const char* track = this->CTest->GetSpecificTrack();
  if ( track )
    {
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
      "   Track: " << track << std::endl);
    }

  // Log startup actions.
  std::string startLogFile = binaryDir + "/Testing/Temporary/LastStart.log";
  cmGeneratedFileStream ofs(startLogFile.c_str());
  if(!ofs)
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot create log file: LastStart.log" << std::endl);
    return false;
    }

  // Make sure the source directory exists.
  if(!this->InitialCheckout(ofs, sourceDir))
    {
    return false;
    }
  if(!cmSystemTools::FileIsDirectory(sourceDir.c_str()))
    {
    cmOStringStream e;
    e << "given source path\n"
      << "  " << sourceDir << "\n"
      << "which is not an existing directory.  "
      << "Set CTEST_CHECKOUT_COMMAND to a command line to create it.";
    this->SetError(e.str().c_str());
    return false;
    }

  this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", "OFF");
  this->CTest->SetSuppressUpdatingCTestConfiguration(true);
  int model = this->CTest->GetTestModelFromString(smodel);
  this->CTest->SetTestModel(model);
  this->CTest->SetProduceXML(true);

  return this->CTest->InitializeFromCommand(this);
}

//----------------------------------------------------------------------------
bool cmCTestStartCommand::InitialCheckout(
  std::ostream& ofs, std::string const& sourceDir)
{
  // Use the user-provided command to create the source tree.
  const char* initialCheckoutCommand
    = this->Makefile->GetDefinition("CTEST_CHECKOUT_COMMAND");
  if(!initialCheckoutCommand)
    {
    initialCheckoutCommand =
      this->Makefile->GetDefinition("CTEST_CVS_CHECKOUT");
    }
  if(initialCheckoutCommand)
    {
    // Use a generic VC object to run and log the command.
    cmCTestVC vc(this->CTest, ofs);
    vc.SetSourceDirectory(sourceDir.c_str());
    if(!vc.InitialCheckout(initialCheckoutCommand))
      {
      return false;
      }
    }
  return true;
}
