#pragma once

#include "CompilationTask.h"   

class RunTask : public Task {
	int testcompilationtask_id;
	String binary_name;
	String matrix;
	String environments;
	String usr_par;
	String args;
	CompilationTask* parent;
public:
	void print() const override {
		printf("id=%ld; maxtime=%d; testcompilationtask_id=%ld; matrix=%s; environments=%s; usr_par=%s; args=%s kernels=%d\n",
			id,
			maxtime,
			testcompilationtask_id,
			matrix.getCharArray(),
			environments.getCharArray(),
			usr_par.getCharArray(),
			args.getCharArray(),
			kernels
		);
	}

	void setKernels(String* kernels_s) { kernels = atoi(kernels_s->getCharArray()); }
	void setTestCompilationTaskId(String* id_s) { testcompilationtask_id = strtol(id_s->getCharArray(), NULL, 10); }

	int getTestCompilationTaskId() { return testcompilationtask_id; }

	void setMatrix(String* matrix_in) { matrix = String(matrix_in->getCharArray()); }
	void setEnvironments(String* environments_in) { environments = String(environments_in->getCharArray()); }
	void setUsrPar(String* usr_par_in) { usr_par = String(usr_par_in->getCharArray(), '|'); }
	void setArgs(String* args_in) { args = String(args_in->getCharArray()); }
	void setParent(CompilationTask* parent_in) { 
		parent = parent_in;
		binary_name = "spf_" + packageId+"_"+String(id) + "_" + matrix.Replace(' ', '_');
	}

	CompilationTask* getParent() { return parent; }

	RunTask(Text* lines, int offset) :Task(lines, offset) {
		setTestCompilationTaskId(lines->get(offset + 2));
		setMatrix(lines->get(offset + 3));
		setEnvironments(lines->get(offset + 4));
		setUsrPar(lines->get(offset + 5));
		setArgs(lines->get(offset + 6));
		setKernels(lines->get(offset + 7));
		//todo setStartCommand
	}

	RunTask(const nlohmann::json& data) : Task(data) {
		testcompilationtask_id = Utils::getValue<int>(data, "compilation_task_id");
		matrix = Utils::getValue<string>(data, "matrix");
		environments = Utils::getValue<string>(data, "environments");
		usr_par = Utils::getValue<string>(data, "usr_par");
		args = Utils::getValue<string>(data, "args");
		kernels = Utils::getValue<int>(data, "cores");
		//todo setStartCommand
	}

	String getLaunchScriptText() override {
		String modules = userWorkspace + "/modules";
		String starterCall = modules + "/starter";
		String launcherCall = modules + "/launcher";
		//todo вшить команду запуска в задачу на стороне сервера, чтобы в будущем тестировать произвольные задачи.
		String dvm_start = String::DQuotes(dvm_drv) + " run ";
		if (!matrix.isEmpty())
			dvm_start = dvm_start + matrix + " ";
		dvm_start = dvm_start + String::DQuotes("./" + binary_name);
		//--------------------------------------------------------------------------------------
		if (!args.isEmpty())
			dvm_start = dvm_start + " " + args;
		return String::DQuotes(starterCall) + " " +
			String::DQuotes(launcherCall) + " " +
			String(maxtime) + " " +
			String::DQuotes("killall -SIGKILL " + binary_name + " 1>/dev/null 2>/dev/null") + " " +
			dvm_start;
	}

	void prepareWorkspace() override {
		String binary_src = parent->getWorkspace() + "/0";
		String binary_dst = workspace + "/" + binary_name;
		Utils::Ln(binary_src, binary_dst);
		if (!usr_par.isEmpty()) {
			String parPath = String(id) + "/usr.par";
			File parFile = File(parPath, usr_par);
		}
	}
	
	String getStartCommand() override {
		String res = Task::getStartCommand();
		if (!environments.isEmpty())
			res = environments + " " + res;
		return res;
	}

	String copyResults(const String& pathRes) override {
	    String resultPath = Task::copyResults(pathRes);
		if (Utils::Exists(workspace + "/sts.gz+")) {
		    String stsPath(resultPath + "/statistic.txt");
			String dvm_start = String::DQuotes(dvm_drv) + " pa " + String::DQuotes(String(getId()) + "/sts.gz+") + " " + String::DQuotes(stsPath);
			system(dvm_start.getCharArray());
			while (!Utils::Exists(stsPath));
		}
		return resultPath;
	}
};
