#pragma warning (disable: 4786)

#include <time.h>
#include "model.h"
#include "utils.h" 

using namespace std;

static void usage(const char *prog_name); 
static int parse_args(int argc, char **argv, model *pmodel); 

int main(int argc, char **argv) {
    model atot; 
	time_t start, finish; 

	// parse command line
	if (parse_args(argc, argv, &atot) == EXIT_FAILURE) {
		return EXIT_FAILURE; 
	}

	time(&start); 

	// initialize
    if (atot.init() == EXIT_FAILURE) {
		return EXIT_FAILURE; 
    }

	// parameter estimation
	atot.estimate(); 

	time(&finish); 
	fprintf(stdout, "%s takes %g seconds.\n", argv[0], difftime(finish, start));
    
    return EXIT_SUCCESS; 
}

void usage(const char *prog_name) {
	fprintf(stdout, "%s v1.0: Author-Topic over Time (AToT) Model.\n", prog_name); 
	fprintf(stdout, "**Task: To estimate parameters from scratch**\n"); 
	fprintf(stdout, "Author: XU Shuo (pzczxs@gmail.com)\n\n"); 
	fprintf(stdout, "Usage: %s [options] -dfile <string>\n", prog_name); 
	fprintf(stdout, "       -dfile <string>: The input training data file\n"); 
	fprintf(stdout, 
		"       Options:\n"
		"         -alpha <double>: The value of alpha, hyper-parameter of AToT (default 50/ntopics)\n"
		"         -beta <double>: The value of beta, hyper-parameter of AToT (default 0.1)\n"
		"         -seed <int>: random number seed (default time())\n"
		"         -ntopics <int>: The number of topics (default 100)\n"
		"         -niters <int>: The number of Gibbs sampling iterations (default 2000)\n"
		"         -savestep <int>: The step for Gibbs sampling iterations at which the AT model is saved (default 0)\n"
		"         -twords <int>: The number of most likely words for each topic (default 20)\n"
		"         -tauthors <int>: The number of most likely authors for each topic (default 20)\n"
		); 
	fprintf(stdout, "\n"); 
}

static int parse_args(int argc, char **argv, model *pmodel) {
    string dir = ""; 
    string model_name = ""; 
    string dfile = ""; 
    double alpha = -1.0; 
    double beta = -1.0; 
	int seed = utils::get_seed(); 
    int K = 0; 
    int niters = 0; 
    int savestep = 0; 
    int twords = 20; 
	int tauthors = 20; 

	for (int i = 0; i < argc; i++) {
		string arg = argv[i]; 
	
		if (arg == "-dir") {
			dir = argv[++i]; 
		} else if (arg == "-dfile") {
			dfile = argv[++i]; 
		} else if (arg == "-model") {
			model_name = argv[++i];	
		} else if (arg == "-alpha") {
			alpha = atof(argv[++i]); 
		} else if (arg == "-beta") {
			beta = atof(argv[++i]); 
		} else if (arg == "-seed") {
			seed = atoi(argv[++i]); 
		} else if (arg == "-ntopics") {
			K = atoi(argv[++i]); 
		} else if (arg == "-niters") {
			niters = atoi(argv[++i]); 
		} else if (arg == "-savestep") {
			savestep = atoi(argv[++i]); 
		} else if (arg == "-twords") {
			twords = atoi(argv[++i]); 
		} else if (arg == "-tauthors") {
			tauthors = atoi(argv[++i]); 
		} else if (arg == "-help") {
			usage(argv[0]); 
			return EXIT_FAILURE; 
		} else {
			;	// do noting
		}	
    }

	if (dfile == "") {
		utils::print_error("Please specify the input data file for model estimation!\n"); 
		return EXIT_FAILURE; 
	}
	
	if (K > 0) {
		pmodel->K = K;
	}
	
	pmodel->alpha = (alpha >= 0.0)? alpha: 50.0 / pmodel->K; 
	
	if (beta >= 0.0) {
		pmodel->beta = beta;
	}
	
	if (niters > 0) {
		pmodel->niters = niters;
	}
	
	if (savestep > 0) {
		pmodel->savestep = savestep;
	}
	
	if (twords > 0) {
		pmodel->twords = twords;
	}

	if (tauthors > 0) {
		pmodel->tauthors = tauthors; 
	}

	pmodel->dfile = dfile;
	
	string::size_type idx = dfile.find_last_of("/");			
	if (idx == string::npos) {
		pmodel->dir = "./";
	} else {
		pmodel->dir = dfile.substr(0, idx + 1);
		pmodel->dfile = dfile.substr(idx + 1, dfile.size() - pmodel->dir.size());
		fprintf(stdout, "dir = %s\n", pmodel->dir.c_str());
		fprintf(stdout, "dfile = %s\n", pmodel->dfile.c_str());
	}
    
    return EXIT_SUCCESS;
}