#include "base/loggers.h"
#include "../test_util.h"
#include "osutils.h"
#include "UnitTest++.h"
#include <string>
#include <stdexcept>
#include <sys/stat.h>
#include <sys/types.h>

#ifndef WIN32
#include <unistd.h>
#endif

using namespace bdm;

int get_file_size ( const char *fname ) {
	struct stat st;
	if ( stat ( fname, &st ) ) {
		std::string msg = "can't stat ";
		msg += fname;
		throw std::runtime_error ( msg );
	}

	int sz = static_cast<int> ( st.st_size );
	if ( sz != st.st_size ) {
		std::string msg = fname;
		msg += " too big";
		throw std::runtime_error ( msg );
	}

	return sz;
}

TEST ( memlog_test ) {
	RV th = RV ( "{alog blog }" );
	RV r = RV ( "{r }", "2" );

	string ls ( "memlog_test" );
	remove_all ( ls.c_str() );

	memlog logger ( 100, ls );

	int pol = 11;

	int rid = logger.add_vector ( r, "" );
	int thid = logger.add_vector ( th, "th" );
	int polid = logger.add_setting ( "pols" );

	logger.init();

	for ( int i = 0; i < 10; i++ ) {
		logger.log_vector ( rid, vec_2 ( ( double ) i, ( double ) ( i + 1 ) ) );
		logger.log_vector ( thid, vec_2 ( ( double ) ( 100 - i ), ( double ) ( i - 50 ) ) );
		UI::save ( pol, logger.log_to_setting ( polid ), "polozka" );
		logger.step();
	}

	logger.finalize();

	CHECK_EQUAL ( get_file_size ( "logger_test.matrix" ), get_file_size ( ( ls + ".it" ).c_str() ) );
	CHECK_EQUAL ( get_file_size ( ( ls + ".cfg.check" ).c_str() ), get_file_size ( ( ls + ".cfg" ).c_str() ) );
}

TEST ( dirfilelog_test ) {
	RV th = RV ( "{alog blog }" );
	RV r = RV ( "{r }", "2" );

	string ls ( "exp" );
	remove_all ( ls.c_str() );
	makedir ( ls, false );
	remove_all ( "dirfilelog_files" );

	dirfilelog L ( "dirfilelog_files", 10 );

	int rid = L.add_vector ( r, "" );
	int thid = L.add_vector ( th, "th" );

	L.init();

	for ( int i = 0; i < 150; i++ ) {
		L.log_vector ( rid, vec_2 ( ( double ) i, ( double ) ( i + 1 ) ) );
		L.log_vector ( thid, vec_2 ( ( double ) ( 100 - i ), ( double ) ( i - 50 ) ) );
		L.step();
	}

	L.finalize();

	std::string expected ( load_test_file ( "logger_test_dirfile_format.matrix" ) );
	std::string actual ( load_test_file ( "dirfilelog_files/format" ) );
	CHECK_EQUAL ( expected, actual );
}
