/*
 * localClient.cpp
 *
 *  Created on: Aug 22, 2017
 *      Author: vadims
 */

#include <thread> 
#include <future>
#include <fstream>
#include "localClient.hpp"
#include "nlohmann/json.hpp"
#include "easylogging++/easylogging++.h"
#include "misc/messagedata.hpp"


using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
using json = nlohmann::json;

localClient::localClient()
{
	client.set_access_channels(websocketpp::log::alevel::none);
	//client.clear_access_channels(websocketpp::log::alevel::none);
	client.init_asio();
	client.set_open_handler(bind(&localClient::on_open, this));
	client.set_message_handler(bind(&localClient::on_message, this, ::_1, ::_2));
}


void localClient::on_message(websocketpp::connection_hdl hdl, message_ptr msg)
{
	manager.addJob(msg->get_payload(), hdl);

	if (Job::getCommandFromInput(msg->get_payload()) == "close") {
		LOG(INFO) << "Stopping client ";
		client.stop();
	}
}

void localClient::on_open()
{
	LOG(INFO) << "Opened client ";
}


void localClient::run()
{
	LOG(INFO) << "in localClient::run ";

	websocketpp::lib::error_code ec;
	websocketpp::client<websocketpp::config::asio_client>::connection_ptr con = client.get_connection(localClient::uri(), ec);
	if (ec) {
		LOG(ERROR) << "Could not get connection: " << ec.message();
		return;
	}

	client.connect(con);
	LOG(INFO) << "Client start running ";
	try {
		std::thread t0(&JobManager::run, &manager);
		client.run();
		t0.join();
	}
	catch (websocketpp::exception const& e) {
		LOG(ERROR) << "Client exception " << e.what();
		std::cout << "Client exception " << e.what();
	}
	catch (std::exception const& e) {
		LOG(ERROR) << "Client exception " << e.what();
		std::cout << "Client exception " << e.what();
	}
	catch (std::string e)
	{
		LOG(ERROR) << "Client exception " << e;
		std::cout << "Client exception " << e;
	}
}

void localClient::setData(int port_, std::string id_)
{
	LOG(INFO) << "Setting client data ";
	portNr = port_;
	id = id_;
}

void localClient::setLoggingFile(std::string filename)
{
	logFile.open(filename);
	client.get_alog().set_ostream(&logFile);
	client.get_elog().set_ostream(&logFile);
}


std::string localClient::uri()
{
	return "ws://[::1]:" + std::to_string(portNr) + "/?id=" + id;
}
