package de.tudresden.inf.lat.born.owlapi.processor;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Objects;
import java.util.function.Function;

import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;

import de.tudresden.inf.lat.born.core.common.ResourceUtil;
import de.tudresden.inf.lat.born.core.term.Symbol;
import de.tudresden.inf.lat.problogapi.ResourceConstant;

/**
 * An object of this class processes an OWL ontology, produces a ProbLog file,
 * and executes ProbLog to obtain the result.
 * 
 * @author Julian Mendez
 *
 */
public class ProcessorCore {

	public static final String TEMPORARY_INPUT_FILE_FOR_PROBLOG = ResourceConstant.BORN_WORKING_DIRECTORY
			+ ResourceConstant.FILE_SEPARATOR + "temporary_input_for_problog.txt";

	private boolean isShowingLog = false;

	/**
	 * Constructs a new processor.
	 */
	public ProcessorCore() {
	}

	/**
	 * Reads all the content provided by a reader and stores it in a string
	 * buffer.
	 * 
	 * @param sbuf
	 *            string buffer to store the content provided by the reader
	 * @param input
	 *            reader
	 * @throws IOException
	 *             if something goes wrong with I/O
	 */
	void show(StringBuffer sbuf, Reader input) throws IOException {
		Objects.requireNonNull(sbuf);
		Objects.requireNonNull(input);
		BufferedReader reader = new BufferedReader(input);
		for (String line = reader.readLine(); Objects.nonNull(line); line = reader.readLine()) {
			sbuf.append(line);
			sbuf.append(Symbol.NEW_LINE_CHAR);
		}
	}

	/**
	 * Shows the entry on the standard output, if logging is enabled.
	 * 
	 * @param str
	 *            entry to log
	 * @param start
	 *            execution start
	 */
	void log(String str, long start) {
		Objects.requireNonNull(str);
		Objects.requireNonNull(start);
		long current = System.nanoTime();
		String info = "" + (current - start) + Symbol.TAB_AND_COLON + str;
		if (this.isShowingLog) {
			System.out.println(info);
		}
	}

	/**
	 * Creates the content of the ProbLog input file and returns this content as
	 * a string.
	 * 
	 * @param start
	 *            execution start
	 * @param useOfDefaultCompletionRules
	 *            use of default completion rules
	 * @param additionalCompletionRules
	 *            additional completion rules
	 * @param ontology
	 *            OWL ontology
	 * @param bayesianNetwork
	 *            Bayesian network
	 * @param query
	 *            query
	 * @param executionResult
	 *            execution result
	 * @return the content of the ProbLog input file
	 * @throws OWLOntologyCreationException
	 *             if the ontology was not created
	 * @throws IOException
	 *             if something goes wrong with I/O
	 */
	String createProblogFile(long start, boolean useOfDefaultCompletionRules, String additionalCompletionRules,
			OWLOntology ontology, String bayesianNetwork, String query, ProcessorExecutionResult executionResult)
					throws OWLOntologyCreationException, IOException {
		Objects.requireNonNull(additionalCompletionRules);
		Objects.requireNonNull(ontology);
		Objects.requireNonNull(bayesianNetwork);
		Objects.requireNonNull(query);
		log("Create ProbLog file.", start);
		ProblogInputCreator instance = new ProblogInputCreator();
		String ret = instance.createProblogFile(useOfDefaultCompletionRules, additionalCompletionRules, ontology,
				bayesianNetwork, query, new FileOutputStream(ResourceUtil.ensurePath(TEMPORARY_INPUT_FILE_FOR_PROBLOG)),
				executionResult);
		return ret;

	}

	public void run(ProcessorConfiguration conf, long start, ProcessorExecutionResult executionResult) {
		long processorStart = System.nanoTime();
		Objects.requireNonNull(conf);
		Objects.requireNonNull(executionResult);
		StringBuffer sbuf = new StringBuffer();
		try {
			log("Start. Each row shows nanoseconds from start and task that is starting.", start);

			Function<Reader, String> queryProcessor = conf.getQueryProcessor();

			String info = createProblogFile(start, conf.hasDefaultCompletionRules(),
					conf.getAdditionalCompletionRules(), conf.getOntology(), conf.getBayesianNetwork(), conf.getQuery(),
					executionResult);
			log(info, start);

			long queryProcessingStart = System.nanoTime();
			String result = queryProcessor.apply(new FileReader(TEMPORARY_INPUT_FILE_FOR_PROBLOG));
			executionResult.setProblogReasoningTime(System.nanoTime() - queryProcessingStart);

			log("End and show results.", start);

			sbuf.append(result);

		} catch (IOException | OWLOntologyCreationException e) {
			throw new RuntimeException(e);
		}

		executionResult.setResult(sbuf.toString());
		executionResult.setTotalTime(System.nanoTime() - processorStart);
	}

}

@@ -96,45 +96,122 @@
 .io.
-FileOutputStream;%0Aimport java.io.File
+ByteArrayInputStream;%0Aimport java.io.ByteArrayOutputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStream
 Read
@@ -225,35 +225,36 @@
 ort java.io.
-IOException
+OutputStream
 ;%0Aimport jav
@@ -487,135 +487,19 @@
 ore.
-common.ResourceUtil;%0Aimport de.tudresden.inf.lat.born.core.term.Symbol;%0Aimport de.tudresden.inf.lat.problogapi.ResourceConstant
+term.Symbol
 ;%0A%0A/
@@ -696,186 +696,8 @@
  %7B%0A%0A
-%09public static final String TEMPORARY_INPUT_FILE_FOR_PROBLOG = ResourceConstant.BORN_WORKING_DIRECTORY%0A%09%09%09+ ResourceConstant.FILE_SEPARATOR + %22temporary_input_for_problog.txt%22;%0A%0A
 %09pri
@@ -2405,24 +2405,84 @@
 tion result%0A
+%09 * @param inputForProblog%0A%09 *            input for ProbLog%0A
 %09 * @return 
@@ -2902,15 +2902,43 @@
 sult
-)
+,
 %0A%09%09%09
-%09%09
+OutputStream inputForProblog) 
 thro
@@ -3387,93 +3387,25 @@
 ry, 
-new FileOutputStream(ResourceUtil.ensurePath(TEMPORARY_INPUT_FILE_FOR_PROBLOG)),%0A%09%09%09%09
+inputForProblog, 
 exec
@@ -3432,17 +3432,16 @@
 rn ret;%0A
-%0A
 %09%7D%0A%0A%09pub
@@ -3869,16 +3869,97 @@
 sor();%0A%0A
+%09%09%09ByteArrayOutputStream inputForProblogByteArray = new ByteArrayOutputStream();%0A
 %09%09%09Strin
@@ -4148,24 +4148,50 @@
 cutionResult
+, inputForProblogByteArray
 );%0A%09%09%09log(in
@@ -4260,93 +4260,183 @@
 %0A%09%09%09
-String result = queryProcessor.apply(new FileReader(TEMPORARY_INPUT_FILE_FOR_PROBLOG)
+Reader inputForProblog = new InputStreamReader(%0A%09%09%09%09%09new ByteArrayInputStream(inputForProblogByteArray.toByteArray()));%0A%09%09%09String result = queryProcessor.apply(inputForProblog
 );%0A%09

Simplify ProbLog execution by avoiding the creation of a temporary file