﻿// cenos.cpp : Defines the entry point for the application.
//
#ifdef USE_VLD
#include <vld.h>
#endif

#include <mystdlib.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <thread>

#include "cenosServer.hpp"
#include "localClient.hpp"
#include "misc/batchRunner.hpp"
#include "misc/crashReport.h"
#include "misc/miscFunctions.hpp"

#include <websocketpp/config/asio_no_tls.hpp>
#include "easylogging++/easylogging++.h"

INITIALIZE_EASYLOGGINGPP

void initializeLogging(std::string);

int main(int argc, char* argv[])
{
#ifdef WIN32
	SetErrorMode(SEM_FAILCRITICALERRORS);
	SetUnhandledExceptionFilter(generate_dump_file);
#endif
	try
	{
		std::string logPrefix = misc::getLogPrefix();
		initializeLogging(logPrefix + ".cenos-backend.log");
		if (argc < 2)
		{
			LOG(INFO) << "Not enough arguments passed.";
			return 0;
		}

		localClient backendClient;
		backendClient.setData(stoi(argv[1]), "backend");
		backendClient.setLoggingFile(logPrefix + ".ws-backend-client.log");

		cenosServer::readClientNames();  // read client names for cenosServer
		cenosServer backendServer;
		backendServer.setLoggingFile(logPrefix + ".ws-backend-server.log");


		// initialize backend server
		if (backendServer.init(stoi(argv[1])))
		{
			LOG(INFO) << "Backend server initialized.";

			misc::getdp_info();
		}
		else
		{
			LOG(ERROR) << "Could not initialize backend server.";
			std::cout << "Could not initialize backend server.\n";
			return 0;
		}

		// run backendClient in thread t2
		std::thread t2(&localClient::run, std::ref(backendClient));

		Sleep(100);

		std::thread t1(&cenosServer::run, &backendServer);

		t1.join();
		t2.join();
	}
	catch (std::exception &e)
	{
		LOG(ERROR) << "Exception caught " << e.what();
		std::cout << "Exception caught " << e.what();
	}

	LOG(INFO) << "cenos-backend.exe finished";
	return 0;
}

void initializeLogging(std::string filename)
{
	std::string confFile = "*GLOBAL:\n FORMAT = %datetime %level %msg\n ENABLED = true\n FILENAME = " + filename + "\n TO_FILE = true\n TO_STANDARD_OUTPUT = false\n LOG_FLUSH_THRESHOLD  = 1";

	el::Configurations c;
	c.setToDefault();
	c.parseFromText(confFile);
	el::Loggers::reconfigureAllLoggers(c);
	el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog);
	el::Loggers::addFlag(el::LoggingFlag::ImmediateFlush);
}
