/* Distributed under the Apache License, Version 2.0.
   See accompanying NOTICE file for details.*/

#include "RunUtils.h"
#include "LBMUtils.h"
#include <fstream>
#include <iostream>


LBM::RunConfig::RunConfig()
{
  ParseRunConfig();
}

LBM::RunConfig::~RunConfig()
{

}

void LBM::RunConfig::PrintUsage()
{
  std::cout << "Usage: <option(s)>"
    << "Options:\n"
    << "  -h,--help          Show this help message\n"
    << "  -l,--legacy PATH   Specify the root path to search for legacy file sets."
    << "                     A legacy set must have these 3 files"
    << "                         - grid.data"
    << "                         - setprob.data"
    << "                         - voxelgrid.data"
    << "                     Each set of legacy files should be in its own folder"
    << std::endl;
}

void LBM::RunConfig::ParseArgs(int argc, char* argv[])
{
  std::vector <std::string> sources;
  std::string destination;
  for (int i = 1; i < argc; ++i)
  {
    if (std::string(argv[i]) == "--destination")
    {
      if (i + 1 < argc) { // Make sure we aren't at the end of argv!
        destination = argv[i++]; // Increment 'i' so we don't get the argument as the next argv[i].
      }
      else 
      { // Uh-oh, there was no argument to the destination option.
        std::cerr << "--destination option requires one argument." << std::endl;
        return;
      }
    }
    else 
    {
      sources.push_back(argv[i]);
    }
  }
}

bool LBM::RunConfig::ParseRunConfig()
{
  if (!m_legacy_dir.empty())
    return true;
  std::string line;
  std::ifstream run_config;
  run_config.open("run.config");
  if (!run_config.good())
    return false;
  while (!run_config.eof()) // To get you all the lines.
  {
    std::getline(run_config, line); // Get the line.
    size_t lpos = line.find("legacy_dir=");
    if (lpos != std::string::npos)
      m_legacy_dir = line.substr(11);
    size_t ipos = line.find("imagery_dir=");
    if (ipos != std::string::npos)
      m_itk_dir = line.substr(12);
    size_t vpos = line.find("verification_dir=");
    if (vpos != std::string::npos)
      m_verification_dir = line.substr(17);
  }
  run_config.close();
  return !m_legacy_dir.empty();
}

const std::vector<LBM::RunIO>& LBM::RunConfig::GetITKDirRuns(std::string const& sub_dir)
{
  return GetITKRuns(m_itk_dir + sub_dir);
}
const std::vector<LBM::RunIO>& LBM::RunConfig::GetITKRuns(std::string const& root)
{
  m_runs.clear();
  std::string search_in = root;
  if (root.empty())
    search_in = m_itk_dir;

  std::vector<std::string> files;
  ListFiles(search_in, files, ".cfg");
  for (std::string file : files)
  {
    LBM::RunIO io;
    io.input = file;
    std::string dir = file.substr(0, file.find_last_of("/"));
    // Create our output directory and name our output files

    std::string name = file.substr(file.find_last_of("/")); // Get File name
    name = name.substr(0, name.find_last_of(".")); // Nix Extension
    std::string out_dir = "./itk_runs";// +name; // TODO mimic input folder hierarchy from root
    CreatePath(out_dir);
    io.output_base_path = out_dir + name;
    m_runs.push_back(io);
  }
  return m_runs;
}

const std::vector<LBM::RunIO>& LBM::RunConfig::GetVerificationDirRuns(std::string const& sub_dir)
{
  return GetVerificationRuns(m_verification_dir + sub_dir);
}
const std::vector<LBM::RunIO>& LBM::RunConfig::GetVerificationRuns(std::string const& root)
{
  m_runs.clear();
  std::string search_in = root;
  if (root.empty())
    search_in = m_verification_dir;

  std::vector<std::string> files;
  ListFiles(search_in, files, ".cfg");
  for (std::string file : files)
  {
    LBM::RunIO io;
    io.input = file;
    std::string dir = file.substr(0, file.find_last_of("/"));
    // Create our output directory and name our output files

    std::string name = dir.substr(dir.find_last_of("/")); // Get dir name
    std::string out_dir = "./verification_runs" + name;
    CreatePath(out_dir);
    io.output_base_path = out_dir + "/";
    m_runs.push_back(io);
  }
  return m_runs;
}
