#include <iostream>
#include <string>

#include "util/OptionParser.h"
#include "Graph.h"

int main(int argc, char* argv[]) {
  popl::OptionParser optionParser("Allowed options");

  auto help_option = optionParser.add<popl::Switch>("h", "help", "Print this help message.");
  auto input_filename = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("f", "input-file", "Filename of input graph file.");
  auto input_string = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("s", "input-string", "Input graph string.");

  auto stdout_output = optionParser.add<popl::Switch, popl::Attribute::optional>("o", "stdout", "Output to stdout.");
  auto file_output = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("p", "output-file", "Filename for output.");

  auto verbose_max_flow = optionParser.add<popl::Switch, popl::Attribute::optional>("a", "max-flow", "Include verbose information about the max flow to the output.");
  auto min_cut_option = optionParser.add<popl::Switch, popl::Attribute::optional>("m", "minimum-cut", "Include the minimum cut set to the output.");

  auto verbose_option = optionParser.add<popl::Switch, popl::Attribute::optional>("v", "verbose", "Output verbose algorithmic information and runtime. Pass twice to get step-by-step information.");

  try {
    optionParser.parse(argc, argv);
    if(parser::checkOption(input_filename->count(), input_string->count()) > 0) {
      std::cout << optionParser << std::endl;
		  return EXIT_FAILURE;
    }

    if(help_option->count() > 0) {
      std::cout << optionParser << std::endl;
    }
  } catch (const popl::invalid_option &e) {
    return parser::printPoplException(e);
  } catch (const std::exception &e) {
		std::cerr << "Exception: " << e.what() << "\n";
		return EXIT_FAILURE;
	}

  std::string filename = "";
  if(file_output->is_set()) {
    filename = file_output->value(0);
  }
  data::Graph network(stdout_output->is_set(),
                      file_output->is_set(),
                      filename,
                      verbose_max_flow->is_set(),
                      min_cut_option->is_set(),
                      verbose_option->count());
  if(input_filename->count() > 0) {
    network.parseFromFile(input_filename->value(0));
  } else if (input_string->count()) {
    network.parseFromString(input_string->value(0));
  }
  network.maxFlowDinic();

  return 0;
}