// C++ std libs
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <sys/time.h>
#include <sys/types.h>

// C++ Boost
#include <boost/program_options.hpp>

// utils
#include "utils.h"

// Classes
#include "Vihgo.h"

using namespace std;
namespace po = boost::program_options;

int main(int argc, char* argv[])
{
  cerr << "Starting Main" << endl;

	bool countStop = false;

	int currentThread = 0;
	int depthThreshold;
	int nbThread = 1;
	int loggingLevel;

	double ratioThreshold;
	double pvalueThreshold;

	string integraseFile;
	string bamFile;
 	string rtFile;
	string proteaseFile;
	string referenceFile;
	string outputFile;
	string codonResultFile;
	string csFile;
	string inRunControlBam;
	string logFile;
	string geneFile;

	po::options_description desc("Allowed options");
	desc.add_options()
	("help,h", "produce help message")

	("input,i",  po::value<string>( &bamFile ), "Input BAM file containing aligned read from sample." )
	("output,o",  po::value<string>( &outputFile ), "output result file variants." )
	("logFile,l",  po::value<string>( &logFile ), "Log file output." )
	("codon,c",  po::value<string>( &codonResultFile ), "output result file variants." )
	("consensus,C",  po::value<string>( &csFile ), "Consensus sequence file (fasta)." )

	("integrase,I",  po::value<string>( &integraseFile ), "File annotation for integrase prot." )
	("rt,R" , po::value<string>( &rtFile ) , "File annotation for retrotranscriptase prot." )
	("protease,P" , po::value<string>( &proteaseFile ) , "File annotation for protease prot." )
	("reference,r" ,  po::value<string>( &referenceFile ) , "Reference Fasta file." )
	("control,b" ,  po::value<string>( &inRunControlBam ) , "In run control BAM file." )
	("gene,g" ,  po::value<string>( &geneFile ) , "Gene annotation file related to reference genome provided." )

	("depth,d", po::value<int>( &depthThreshold )->default_value(50), "Depth treshold to call a variant. (optional)")
	("ratio,a" , po::value<double>( &ratioThreshold )->default_value(0.1) , "Minimum ratio of alt reads to take in account a mutation. (optional)" )
	("pvalue,p" , po::value<double>( &pvalueThreshold )->default_value(0.05) , "pvalue threshold from FET to take in account a mutation. (optional)" )
	("stop,s" , "Activate stop codon detction." )

	("thread,t", po::value<int>( &nbThread )->default_value(50), "Number of thread to use. (NYI)")
	("loglevel,L", po::value<int>( &loggingLevel )->default_value(1), "Logging level.");


	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	// Verif que le nb de thread n'est pas négatif ...
	if( nbThread < 1 )
	{
		nbThread = 1;
		cerr << "You entered a null or negative value for thread number, positionning it to 1. " << endl;
	}


	if( argc <= 1 )
	{
		cerr << "Error while checking program arguments" << endl;
		cerr << desc << "\n";
		return 1;
	}


	// check provided files
	if( bamFile.length( ) > 0 )
	{
		if( !IsFileReadable( bamFile ) )
		{
			cerr << "File provided as input BAM : " << bamFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}
	else
	{
		cerr << "No file provided as input BAM file : stopping" << endl;
		return -1;
	}

	if( integraseFile.length( ) > 0 )
	{
		if( !IsFileReadable( integraseFile ) )
		{
			cerr << "File provided as integrase annotation : " << integraseFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}

	if( rtFile.length( ) > 0 )
	{
		if( !IsFileReadable( rtFile ) )
		{
			cerr << "File provided as retrotranscriptase annotation : " << rtFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}

	if( proteaseFile.length( ) > 0 )
	{
		if( !IsFileReadable( proteaseFile ) )
		{
			cerr << "File provided as protease annotation : " << proteaseFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}

	if( referenceFile.length( ) > 0 )
	{
		if( !IsFileReadable( referenceFile ) )
		{
			cerr << "File provided as reference : " << referenceFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}
	else
	{
		cerr << "No file provided as reference file : stopping" << endl;
		return -1;
	}

	if( inRunControlBam.length( ) > 0 )
	{
		if( !IsFileReadable( inRunControlBam ) )
		{
			cerr << "File provided as control sample BAM file : " << inRunControlBam << " is not accessible : stopping" << endl;
			return -1;
		}
	}
	else
	{
		cerr << "No file provided as control sample BAM file : stopping" << endl;
		return -1;
	}

	if( geneFile.length( ) > 0 )
	{
		if( !IsFileReadable( geneFile ) )
		{
			cerr << "File provided as gene annotation : " << geneFile << " is not accessible : stopping" << endl;
			return -1;
		}
	}
	else
	{
		cerr << "No file provided as gene annotation file : stopping" << endl;
		return -1;
	}


	Vihgo * App = new Vihgo( bamFile , geneFile , rtFile , integraseFile , proteaseFile, referenceFile,outputFile, codonResultFile, csFile, inRunControlBam,depthThreshold, nbThread,loggingLevel, ratioThreshold ,pvalueThreshold, countStop );
  App->mainLoop();


	delete App;
	cerr << "end of main" << endl;
  return 0;
}