/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#include "base/polygraph.h"

#include <limits.h>

#include "xstd/h/iostream.h"
#include <fstream>
#include "xstd/h/iomanip.h"

#include "base/CmdLine.h"
#include "base/opts.h"
#include "base/polyOpts.h"
#include "base/histograms.h"
#include "xstd/gadgets.h"


class MyOpts: public OptGrp {
	public:
		MyOpts():
			theHelpOpt(this,      "help",           "list of options"),
			theVersOpt(this,      "version",        "package version info"),
			theOutFileName(this,  "out <file>",     "redirect console output", "-"),
			theDistr(this,  "distr <numDistr>",     "distribution to test"),
			theStep(this,  "hist_step <%>",      "bin `size' in histogram output", 0.05/100),
			theCount(this,  "count <int>",      "number of trials", 100000)

			{ theDistr.argType("num"); }

		virtual bool validate() const;

	public:
		HelpOpt theHelpOpt;
		VersionOpt theVersOpt;
		StrOpt theOutFileName;
		DistrOpt theDistr;
		DblOpt theStep;
		IntOpt theCount;
} TheOpts;

bool MyOpts::validate() const {
	if (!theDistr)
		cerr << "must specify the distribution to test" << endl;
	else
		return true;
	return false;
}

static
void configureLogs(int prec) {
	if (TheOpts.theOutFileName && TheOpts.theOutFileName != "-")
		redirectOutput(TheOpts.theOutFileName.cstr());

	configureStream(cout, prec);
	configureStream(cerr, prec);
	configureStream(clog, prec);
}

// set some general stuff and
// propogate cmd line options to corresponding objects
static
void configure() {
	configureLogs(2);
}

static
void test() {
	const int count = TheOpts.theCount;
	RndDistr *distr = TheOpts.theDistr.condDistr();
	Histogram *hist = new Log2Hist();

	for (int i = 0; i < count; ++i) {
		hist->record((int)Min(distr->trial(), (double)INT_MAX));
	}

	hist->report(0.01, cout);
	cout << endl << hist->stats();
	delete hist;
}

int main(int argc, char *argv[]) {
	CmdLine cmd;
	cmd.configure(Array<OptGrp*>() << &TheOpts);
	if (!cmd.parse(argc, argv) || !TheOpts.validate() || !TheOpts.validate())
		return -1;

	configure();

	test();

	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1