/*******************************************************
 * Copyright (C) 2017-2020 CENOS Ltd vg@cenos-platform.com
 *
 * This file is part of CENOS.
 *
 * CENOS can not be copied and/or distributed without the express
 * permission of CENOS Ltd
 *******************************************************/

#include "Template_Worker.h"
#include "templates/TemplateBuilder.h"
#include "misc/ProgressIndicator.hpp"

Template_Worker::Template_Worker(std::shared_ptr<Job>& j) : Worker(j)
{
}


messagedata Template_Worker::run(MessageQueue_ messageQueue)
{
	try
	{
		if (assignedJob_->command().compare("generateTemplateGeometry") == 0)
		{

			TemplateBuilder builder(assignedJob_);
			builder.buildTemplate();
			std::string return_msg;
			if (!builder.validate(return_msg))
			{
				return messagedata(messagedata::error, messagedata::response, return_msg, assignedJob_->guid());
			}
			builder.generateGeometry();
			json geometryData;
			geometryData["geometryData"] = builder.getGeometryData()->getJson();
			return messagedata(messagedata::success, messagedata::response, geometryData.dump(), assignedJob_->guid());
		}
		else if (assignedJob_->command().compare("generateTemplateMesh") == 0)
		{
			std::function<void(messagedata)> message_bind = std::bind(&MessageQueue::push, std::ref(messageQueue), std::placeholders::_1);
			ProgressIndicator prog_ind(message_bind, assignedJob_->guid());

			TemplateBuilder builder(assignedJob_);
			builder.setProgressIndicator(std::make_shared<ProgressIndicator>(prog_ind));
			builder.buildTemplate();
			builder.generateGeometry();
			bool stop = false;
			builder.setStopper(&stop);

			auto template_future = std::async(std::launch::async, &TemplateBuilder::generateMesh, builder);

			do
			{
				Sleep(100);

				if (assignedJob_->isStopRequested())
				{
					stop = true;
					template_future.wait();
				}

			} while (template_future.wait_for(std::chrono::milliseconds(1)) != std::future_status::ready);

			template_future.get();

			json geometryData;
			geometryData["geometryData"] = builder.getMeshingData()->getJson();

			return messagedata(messagedata::success, messagedata::response, geometryData.dump(), assignedJob_->guid());
		}
	}
	catch (json::exception& e)
	{
		return generateError("Error during template operation : " + std::string(e.what()));
	}
	catch (std::exception e)
	{
		return generateError("Error during template operation : " + std::string(e.what()));
	}
}