/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2012 University of Bonn. All rights reserved.
 * 
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    MoleCuilder is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoleCuilder.  If not, see .
 */
/*
 * MPQCFragmentController.cpp
 *
 *  Created on: Aug 27, 2012
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
// boost asio needs specific operator new
#include 
#include "CodePatterns/MemDebug.hpp"
#include "MPQCFragmentController.hpp"
#include 
#include "Box.hpp"
#include "Helpers/defs.hpp"
#include "Jobs/MPQCJob.hpp"
#include "LinearAlgebra/RealSpaceMatrix.hpp"
#include "World.hpp"
bool MPQCFragmentController::addJobsFromFiles(
    const std::string &executable,
    const std::vector< boost::filesystem::path > &jobfiles)
{
  std::vector jobs;
  for (std::vector< boost::filesystem::path >::const_iterator iter = jobfiles.begin();
      iter != jobfiles .end(); ++iter) {
    const std::string &filename = (*iter).string();
    if (boost::filesystem::exists(filename)) {
      const JobId_t next_id = getAvailableId();
      LOG(1, "INFO: Creating MPQCCommandJob with filename'"
          +filename+"', and id "+toString(next_id)+".");
      parsejob(jobs, executable, filename, next_id);
    } else {
      ELOG(1, "Fragment job "+filename+" does not exist.");
      return false;
    }
  }
  addJobs(jobs);
  sendJobs(host, port);
  RunService("Adding MPQCJobs");
  return true;
}
/** Creates a MPQCCommandJob with argument \a filename.
 *
 * @param jobs created job is added to this vector
 * @param command mpqc command to execute
 * @param filename filename being argument to job
 * @param nextid id for this job
 */
void MPQCFragmentController::parsejob(
    std::vector &jobs,
    const std::string &command,
    const std::string &filename,
    const JobId_t nextid)
{
  std::ifstream file;
  file.open(filename.c_str());
  ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
  std::string output((std::istreambuf_iterator(file)),
      std::istreambuf_iterator());
  double begin[NDIM] = { 0., 0., 0. };
  RealSpaceMatrix M = World::getInstance().getDomain().getM();
  M *= 1./AtomicLengthToAngstroem;  // scale to atomic length units
  const double size = M.at(0,0);
  double end[NDIM] = { size, size, size };
  ASSERT( M.determinant() == size*size*size,
      "parsejob() - current domain matrix "+toString(M)+" is not cubic.");
  FragmentJob::ptr testJob( new MPQCJob(nextid, output, begin, end, level) );
  jobs.push_back(testJob);
  file.close();
  LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
}