/*******************************************************************************
 * Copyright (c) 2020 RBEI and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v. 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *		Adhith Gopal - Initial API and Implementation
 *		Pavithra Krishna Reddy
 *		Deepthi Murugaiyan
 *		Abirami Bhologa Indiran
 *		Santhosh Gokhale D
 *******************************************************************************/
package org.eclipse.blockchain.core;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.io.FileUtils;
import org.eclipse.blockchain.core.log.EthereumLogService;
import org.eclipse.blockchain.core.model.IOABI;
import org.eclipse.blockchain.core.model.SolidityABI;
import org.eclipse.blockchain.model.ethproject.EthereumProject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.internal.loader.EquinoxClassLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.osgi.framework.Bundle;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Code inside this class is just a prototype so it could contain
 * duplicate/in-efficient code and maybe unwanted code SOLDITY COMPILATION IS
 * TESTED WITH SOLC-0.5.4 version as of NOW
 *
 */
public class CoreCommandExecutor {

	private Process gethServer = null;
	private final String web3jVersion = "web3j-4.5.12";
	/**
	 * As of now only one Geth server instance is considered so everything related
	 * to geth is maintained as member variables
	 */
	private String gethIPC = "";
	private String gethDataDirectory = "";
	private Map<String, String> gethOptions = null;
	private final String solcCommand = "solc-path solidity-file --bin --abi --optimize -o output-directory";
	private final String web3jCommand = "web3j-path solidity generate -a=abi-path -b=bin-path -o=output-directory -p=com.bosch";

	private final Map<String, SolidityABI[]> solidityABIMap = new HashMap<>();
	private static CoreCommandExecutor instance;
	private String gethServerStartError = "";

	private CoreCommandExecutor() {
	}

	/**
	 * This instance is used to handle functionality related to geth and solidity
	 *
	 * @return - CorecommandExecutor instance
	 */
	public static CoreCommandExecutor getInstance() {
		if (instance == null) {
			instance = new CoreCommandExecutor();
		}
		return instance;
	}

	String getGethServerStartError() {
		return this.gethServerStartError;
	}

	/**
	 * To start/stop mining process
	 *
	 * @param start - if true mining will start/ if false mining will stop
	 * @throws IOException          -
	 * @throws InterruptedException -
	 */
	public void mine(final boolean start) throws IOException, InterruptedException {
		Process miner = Runtime.getRuntime().exec("cmd");
		StringJoiner inputStream = new StringJoiner(System.lineSeparator());
		StringJoiner errorStream = new StringJoiner(System.lineSeparator());
		cmdRead(miner, inputStream, true);
		cmdReadError(miner, errorStream, true);

		PrintWriter writer = new PrintWriter(miner.getOutputStream());
		if (start) {
			writer.println("geth attach " + this.gethIPC.replace("\\\\", "\\"));
			writer.println("miner.start(3)");
			writer.close();
			miner.waitFor();
			miner.destroy();
		} else {
			writer.println("geth attach " + this.gethIPC.replace("\\\\", "\\"));
			writer.println("miner.stop()");
			writer.close();
			miner.waitFor();
			miner.destroy();
		}
	}

	private void transferArtifactsFromTempToOutput(final String tempLocation, final String outputLocation,
			final String solName) throws IOException {
		// ABI file
		File abiTempFile = new File(tempLocation + File.separator + solName + ".abi");
		File abiFile = new File(outputLocation + File.separator + solName + ".abi");
		abiFile.createNewFile();
		FileUtils.copyFile(abiTempFile, abiFile);

		// BIN file
		File binTempFile = new File(tempLocation + File.separator + solName + ".bin");
		File binFile = new File(outputLocation + File.separator + solName + ".bin");
		abiFile.createNewFile();
		FileUtils.copyFile(binTempFile, binFile);
	}

	/**
	 * Some osgi internal API are accessed in this method to retrieve the classpath
	 * content of this plugin. It won't be changed until problems pop-up
	 *
	 * @param projectName   -
	 * @param solidityFiles -
	 * @param outputDir     -
	 * @return -
	 * @throws IOException            -
	 * @throws InterruptedException   -
	 * @throws ClassNotFoundException -
	 */
	public String solidityCompile(final String projectName, final List<IResource> solidityFiles,
			final IResource outputDir) throws IOException, InterruptedException, ClassNotFoundException {
		String solcCompilerPath = InstanceScope.INSTANCE.getNode(SecoBlocksPreferenceConstants.SECOBLOCKS_PREF_NODE)
				.get(SecoBlocksPreferenceConstants.SOLIDITY_COMPILER_PREF_KEY, "");
		if (solcCompilerPath.isEmpty()) {
			return "Compiler is not set... Please set it in solidity preference page";
		}
		for (IResource solFile : solidityFiles) {
			String tempLocation = outputDir.getLocation().toOSString() + File.separator + "temp";
			File tempOutputDir = new File(tempLocation);
			if (tempOutputDir.exists() && tempOutputDir.isDirectory()) {
				tempOutputDir.delete();
			}
			tempOutputDir.mkdirs();// Check This

			String compileCommand = this.solcCommand
					.replace("solc-path", getCmdLinePath(solcCompilerPath + File.separator + "solc"))
					.replace("solidity-file", getCmdLinePath(solFile.getLocation().toOSString()))
					.replace("output-directory", getCmdLinePath(tempOutputDir.getAbsolutePath()));

			Process solcExe = Runtime.getRuntime().exec("cmd");
			StringJoiner inputStream = new StringJoiner(System.lineSeparator());
			StringJoiner errorStream = new StringJoiner(System.lineSeparator());

			cmdRead(solcExe, inputStream, false);
			cmdReadError(solcExe, errorStream, false);

			PrintWriter writer = new PrintWriter(solcExe.getOutputStream());
			writer.println(compileCommand);
			writer.close();

			solcExe.waitFor();
			solcExe.destroy();
			if (inputStream.toString().contains("Error") || errorStream.toString().contains("Error")) {
				EthereumLogService.INSTANCE.errorLog(inputStream.toString());
				EthereumLogService.INSTANCE.errorLog(errorStream.toString());
				System.err.println(inputStream.toString());
				System.err.println(errorStream.toString());
				return "Some errors occurred during compilation please check the console!!!";
			}
			/**
			 * (In B.sol -> 2 contracts A(Abstract) and B), the actual implementation of A
			 * is present separately. In this case Abstract A's abi and bin replace actual
			 * A's abi and bin during solidity compilation. That is why this temp concept is
			 * introduced, when B.sol is compiled it generates B's abi and bin as well as
			 * Abstract A's abi and bin. This Abstract A is not required to be deployed but
			 * is required for solididty compilation.
			 */
			transferArtifactsFromTempToOutput(tempOutputDir.getAbsolutePath(), outputDir.getLocation().toOSString(),
					solFile.getName().replace(".sol", ""));
			// Reading abi json
			storeABIinSolidityMap(
					outputDir.getLocation().toOSString() + File.separator + solFile.getName().replace(".sol", ".abi"),
					solFile.getLocation().toOSString());

			// Solidity ABI javaType update
			CoreCommandExecutor.getInstance().updateSolABIMap(solFile.getLocation().toOSString(), updateSolJavaTypes(
					CoreCommandExecutor.getInstance().getSolABIMap(solFile.getLocation().toOSString())));

			// Remove old contract from deploymentModel
			ProjectCreator.getInstance().removeDeploymentModelForResource(solFile,
					Web3jHandler.getInstance().getSelectedEnvironment());

			// Java Wrapper Creation
			String web3jCmd = this.web3jCommand.replace("web3j-path", "web3j")
					.replace("abi-path",
							getCmdLinePath(outputDir.getLocation().toOSString() + File.separator
									+ solFile.getName().replace(".sol", ".abi")))
					.replace("bin-path",
							getCmdLinePath(outputDir.getLocation().toOSString() + File.separator
									+ solFile.getName().replace(".sol", ".bin")))
					.replace("output-directory", getCmdLinePath(outputDir.getLocation().toOSString()));
			Process web3jExe = Runtime.getRuntime().exec("cmd");

			cmdRead(web3jExe, inputStream, false);
			cmdReadError(web3jExe, errorStream, false);

			writer = new PrintWriter(web3jExe.getOutputStream());

			/**
			 * The current directory is changed because web3j cli input string is limited
			 */
			writer.println("cd " + getCmdLinePath(unzipAndGetWeb3jPath()));

			writer.println("set JAVA_HOME=" + getJDKPath());

			writer.println(web3jCmd);

			ClassLoader classLoader = CoreCommandExecutor.class.getClassLoader();
			ClasspathEntry[] hostClasspathEntries = ((EquinoxClassLoader) classLoader).getClasspathManager()
					.getHostClasspathEntries();
			String cp = "";
			for (ClasspathEntry c : hostClasspathEntries) {
				cp = cp + c.getBundleFile().getBaseFile().toString() + ";";
			}

			writer.println("javac "
					+ getCmdLinePath(outputDir.getLocation().toOSString() + File.separator + "com" + File.separator
							+ "bosch" + File.separator + solFile.getName().replace(".sol", ".java"))
					+ " -cp " + getCmdLinePath(cp));
			writer.close();

			web3jExe.waitFor();
			web3jExe.destroy();

			ProjectCreator.getInstance().addCompiledSolidityFiles(solFile);
			FileUtils.deleteDirectory(tempOutputDir);
			EthereumLogService.INSTANCE.log(inputStream.toString());
			EthereumLogService.INSTANCE.errorLog(errorStream.toString());
			System.err.println(inputStream.toString());
			System.err.println(errorStream.toString());
		}

		return "";
	}

	private String getCmdLinePath(final String path) {
		return "\"" + path + "\"";
	}

	private SolidityABI[] updateSolJavaTypes(final SolidityABI[] solABI) throws ClassNotFoundException {
		SolidityABI[] updatedSolABI = new SolidityABI[solABI.length];
		for (int i = 0; i < solABI.length; i++) {
			updatedSolABI[i] = solABI[i];
			if (updatedSolABI[i].getInputs() != null) {
				for (IOABI ioa : updatedSolABI[i].getInputs()) {
					SolidityToJavaDataTypeResolver.getInstance().assignJavaType(ioa.getType(), ioa);
				}
			}
			if (updatedSolABI[i].getOutputs() != null) {
				for (IOABI ioa : updatedSolABI[i].getOutputs()) {
					SolidityToJavaDataTypeResolver.getInstance().assignJavaType(ioa.getType(), ioa);
				}
			}
		}

		return updatedSolABI;
	}

	private String unzipAndGetWeb3jPath() throws IOException {
		Bundle bundle = Platform.getBundle("org.eclipse.blockchain.core");
		return unzipWeb3jZip(FileLocator.toFileURL(bundle.getEntry("res/" + this.web3jVersion + ".zip")).getPath());
	}

	private String unzipWeb3jZip(final String zipPath) throws IOException {
		ZipFile web3jZip = new ZipFile(zipPath);
		String destinationDir = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
		File web3jZipContainer = new File(destinationDir + File.separator + "web3jContainer");
		if (!web3jZipContainer.exists()) {
			web3jZipContainer.mkdir();
			final byte[] buf = new byte[4096];
			final Enumeration<? extends ZipEntry> zipEnum = web3jZip.entries();
			while (zipEnum.hasMoreElements()) {
				final ZipEntry item = zipEnum.nextElement();

				if (item.isDirectory()) {
					final File newdir = new File(web3jZipContainer + File.separator + item.getName());
					newdir.mkdir();
				} else {
					final String newfilePath = web3jZipContainer + File.separator + item.getName();
					final File newFile = new File(newfilePath);
					if (!newFile.getParentFile().exists()) {
						newFile.getParentFile().mkdirs();
					}
					try (InputStream is = web3jZip.getInputStream(item);
							FileOutputStream fos = new FileOutputStream(newfilePath);) {

						int len;
						while ((len = is.read(buf)) > 0) {
							fos.write(buf, 0, len);
						}
						is.close();
						fos.close();
					}
				}
			}
		}
		web3jZip.close();

		return web3jZipContainer.getAbsolutePath() + File.separator + this.web3jVersion + File.separator + "bin";
	}

	/**
	 * @return -
	 * @throws IOException          -
	 * @throws InterruptedException -
	 */
	public String getJDKPath() throws IOException, InterruptedException {
		String jdkPath = "";
		Process process = Runtime.getRuntime().exec("cmd");
		PrintWriter writer = new PrintWriter(process.getOutputStream());

		StringJoiner readJDKPath = new StringJoiner(System.lineSeparator());
		cmdRead(process, readJDKPath, true);

		writer.println("where javac");
		writer.close();

		process.waitFor();
		process.destroy();

		String[] lines = readJDKPath.toString().split(System.lineSeparator());
		for (String line : lines) {
			if (line.contains("javac.exe")) {
				jdkPath = line.replace("\\bin\\javac.exe", "").replace("\\", "\\\\");
				break;
			}
		}

		return getCmdLinePath(jdkPath);
	}

	private void storeABIinSolidityMap(final String abiPath, final String solidityFilePath) throws IOException {
		String abiJson = readABI(abiPath);
		ObjectMapper jsonMapper = new ObjectMapper();
		SolidityABI[] readValue = jsonMapper.readValue(abiJson, SolidityABI[].class);
		for (SolidityABI sabi : readValue) {
			if (sabi.isPayable()) {
				IOABI[] inputs = sabi.getInputs();
				IOABI[] newInputs = new IOABI[inputs.length + 1];
				for (int o = 0; o < inputs.length; o++) {
					newInputs[o] = inputs[o];
				}
				IOABI payableInput = new IOABI();
				payableInput.setName("payableAmount");
				payableInput.setType("uint256");
				newInputs[inputs.length] = payableInput;
				sabi.setInputs(newInputs);
			}
		}
		this.solidityABIMap.put(solidityFilePath, readValue);
	}

	/**
	 * @param solPath         - The absolute path of solidity file
	 * @param onlyConstructor - If true will return only constructor ui components
	 * @return - The UI content to be constructed in transactions view
	 */
	public Map<String, String> getUIComponentForSolidityFile(final String solPath, final boolean onlyConstructor,
			final String projectName) {
		SolidityABI[] solABi = this.solidityABIMap.get(solPath);
		Map<String, String> uiMap = new HashMap<>();
		if (!onlyConstructor) {// Check to see whether the contract is deployed
								// in current environment
			EthereumProject ethProject = ProjectCreator.getInstance().getEthProject(projectName);
			IFile file = ethProject.getProject()
					.getFile(solPath.replace(ethProject.getProject().getLocation().toOSString(), ""));

			if (!ProjectCreator.getInstance().isSCDeployed(file, Web3jHandler.getInstance().getSelectedEnvironment())) {
				return uiMap;
			}
		}

		if (solABi != null) {
			for (SolidityABI sABI : solABi) {
				if (sABI.getType().equalsIgnoreCase("constructor")) {
					if (onlyConstructor) {
						String key = "deploy";
						IOABI[] inputs = sABI.getInputs();
						String value = constructUIValue(inputs);
						uiMap.put(key, value);
					}
				} else if (sABI.getType().equalsIgnoreCase("function")) {
					if (!onlyConstructor) {
						String key = sABI.getName();
						IOABI[] inputs = sABI.getInputs();
						String value = constructUIValue(inputs);
						uiMap.put(key + "-" + value, value);
					}
				}
			}
		}

		return uiMap;
	}

	private String constructUIValue(final IOABI[] inputs) {
		StringJoiner uiElemString = new StringJoiner(";");
		for (IOABI input : inputs) {
			uiElemString.add(input.getJavaType().getSimpleName());
		}
		return uiElemString.toString();
	}

	/**
	 * @param abiPath -
	 * @return -
	 */
	public SolidityABI[] getSolABIMap(final String abiPath) {
		return this.solidityABIMap.get(abiPath);
	}

	/**
	 * @param abiPath       -
	 * @param updatedSolABI -
	 */
	public void updateSolABIMap(final String abiPath, final SolidityABI[] updatedSolABI) {
		this.solidityABIMap.put(abiPath, updatedSolABI);
	}

	private String readABI(final String abiPath) throws IOException {
		StringJoiner sj = new StringJoiner("");
		try (BufferedReader br = new BufferedReader(new FileReader(new File(abiPath)))) {
			String line = "";
			while ((line = br.readLine()) != null) {
				sj.add(line);
			}
		}
		return sj.toString();
	}

	/**
	 * @return -
	 * @throws IOException          -
	 * @throws InterruptedException -
	 */
	public String isGethInstalled() throws IOException, InterruptedException {
		/**
		 * This is not fully constructed but this should be first step check when
		 * someone tries to invoke ethereum project creation
		 */
		StringJoiner inputStream = new StringJoiner(System.lineSeparator());
		StringJoiner errorStream = new StringJoiner(System.lineSeparator());
		String gethCheck = "";
		Process gethProcess = Runtime.getRuntime().exec("cmd");
		cmdRead(gethProcess, inputStream, true);
		cmdReadError(gethProcess, errorStream, true);

		PrintWriter processWriter = new PrintWriter(gethProcess.getOutputStream());
		processWriter.println("geth version");
		processWriter.close();

		gethProcess.waitFor();
		gethCheck = errorStream.toString();
		gethProcess.destroy();
		return gethCheck;
	}

	/**
	 * @param dataDir          -
	 * @param initFilePath     -
	 * @param localGethOptions -
	 * @return - Return if any error occurs during server start
	 * @throws IOException          -
	 * @throws InterruptedException
	 */
	public String startGethServer(final String dataDir, final String initFilePath,
			final Map<String, String> localGethOptions) throws IOException, InterruptedException {
		if (isGethInstalled()
				.equals(NLS.bind(CoreCommandMessages.FRAMEWORK_NOT_INSTALLED, "'geth'", System.lineSeparator()))) {
			return "Either Geth is not installed (or) its reference is not set in PATH env variable";
		}
		if (!Web3jHandler.getInstance().getSelectedEnvironment()
				.equals(SecoBlocksPreferenceConstants.EnvironmentType.GETH_CLIENT.toString())) {
			return "Geth environment is not chosen in SecoBlocks -> Environment preference!!!";
		}
		this.gethServerStartError = "Geth";
		StringJoiner inputStream = new StringJoiner(System.lineSeparator());
		StringJoiner errorStream = new StringJoiner(System.lineSeparator());
		this.gethDataDirectory = dataDir;
		CoreCommandExecutor.getInstance().gethOptions = localGethOptions;
		this.gethServer = Runtime.getRuntime().exec("cmd.exe");
		cmdRead(this.gethServer, inputStream, true);
		cmdReadError(this.gethServer, errorStream, true);

		String initFile = initFilePath;
		String genesisFilePath = dataDir + File.separator + "genesis.json";
		if (new File(genesisFilePath).exists()) {
			initFile = genesisFilePath;
		} else {
			if (initFilePath.isEmpty()) {
				initFile = createGethInitFile(dataDir);
			}
		}
		startGethServerLocal(dataDir, initFile, localGethOptions);
		return "";
	}

	private void startGethServerLocal(final String dataDir, final String initFile,
			final Map<String, String> localGethOptions) {
		PrintWriter processWriter = new PrintWriter(this.gethServer.getOutputStream());
		if (!initFile.isEmpty() && !new File(dataDir + File.separator + "geth").exists()) {
			processWriter
					.println("geth --datadir " + getCmdLinePath(dataDir) + " init " + getCmdLinePath(initFile) + "");
		}
		String args = constructGethArguments(localGethOptions);
		processWriter.println("geth --datadir " + getCmdLinePath(dataDir) + " " + args);
		processWriter.close();
		/**
		 * This below code is required because geth once started won't terminate and it
		 * should not terminate because its a server
		 */
		Display.getDefault().syncExec(() -> {
			new Thread(() -> {
				try {
					this.gethServer.waitFor();
				} catch (InterruptedException e) {
					BlockchainCore.getInstance().logException("", e.getMessage(), e);
				}
			}, "Geth Server").start();
		});
	}

	/**
	 * @return - True if geth is started/ false otherwise
	 */
	public boolean isGethStarted() {
		return (this.gethServer != null) && this.gethServer.isAlive() && !this.gethIPC.isEmpty();
	}

	/**
	 * @return - The geth server data directory
	 */
	public String getDataDir() {
		return this.gethDataDirectory;
	}

	/**
	 * @return -The geth command line options
	 */
	public Map<String, String> getGethOptions() {
		return this.gethOptions;
	}

	/**
	 * @return - Returns the default network id
	 */
	public String getDefaultNetworkIdForGeth() {
		String defaultNetworkId = "";
		try (BufferedReader br = new BufferedReader(
				new InputStreamReader(CoreCommandExecutor.class.getResourceAsStream("genesis.template")));) {
			String genesisContent = "";
			while ((genesisContent = br.readLine()) != null) {
				if (genesisContent.contains("chainId")) {
					defaultNetworkId = genesisContent.substring(genesisContent.indexOf(':') + 1).replace(",", "")
							.trim();
				}
			}
		} catch (IOException e) {
			BlockchainCore.getInstance().logException("", e.getMessage(), e);
		}
		return defaultNetworkId;
	}

	private String constructGethArguments(final Map<String, String> localGethOptions) {
		StringJoiner arguments = new StringJoiner(" ");
		localGethOptions.forEach((k, v) -> arguments.add("--" + k + "" + (v.isEmpty() ? "" : " " + v)));
		return arguments.toString();
	}

	/**
	 * Terminate geth server
	 */
	public void terminateGethServer() {
		if (CoreCommandExecutor.getInstance().gethServer != null) {
			this.gethIPC = "";
			this.gethServer.destroyForcibly();
			try {
				Process terminator = Runtime.getRuntime().exec("cmd.exe");
				PrintWriter pw = new PrintWriter(terminator.getOutputStream());
				pw.println("taskkill /F /IM geth.exe");
				pw.close();

				terminator.waitFor();
				terminator.destroy();
			} catch (IOException | InterruptedException e) {
				BlockchainCore.getInstance().logException("", e.getMessage(), e);
			}
		}
	}

	private String createGethInitFile(final String dataDir) throws IOException {
		File gethInitFile = new File(dataDir + File.separator + "genesis.json");
		gethInitFile.createNewFile();// NOSONAR

		try (BufferedReader br = new BufferedReader(
				new InputStreamReader(CoreCommandExecutor.class.getResourceAsStream("genesis.template")));
				BufferedWriter bw = new BufferedWriter(new FileWriter(gethInitFile));) {
			String genesisContent = "";
			while ((genesisContent = br.readLine()) != null) {
				bw.append(genesisContent);
				bw.append(System.lineSeparator());
			}
		}
		return gethInitFile.getAbsolutePath();
	}

	/**
	 * Read output stream of process going to be executed
	 *
	 * @param process     - The process that is going to start
	 * @param inputStream - A log recording object
	 */
	public void cmdRead(final Process process, final StringJoiner inputStream, final boolean logToConsole) {
		Thread processReadThread = new Thread(() -> {
			String line = "";
			try (BufferedReader processReader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {
				while ((line = processReader.readLine()) != null) {
					inputStream.add(line.trim());
					if (line.contains("Error") && this.gethServerStartError.equals("Geth")) {
						this.gethServerStartError = line;
					}
					if (line.contains("IPC endpoint opened")) {
						/*
						 * To determine IPC endpoint when geth server is started.
						 */
						this.gethIPC = line.substring(line.indexOf("url=") + 4);
					}
					if (logToConsole) {
						EthereumLogService.INSTANCE.log(line);
						System.err.println(line);
					}
				}
			} catch (IOException e) {
				BlockchainCore.getInstance().logException("", e.getMessage(), e);
			}
		}, "Process Read Thread");
		processReadThread.start();
	}

	/**
	 * @return - the geth socket handle
	 */
	public String getIPCPath() {
		return this.gethIPC;
	}

	/**
	 * Read error stream of process going to be executed
	 *
	 * @param process     - The process that is going to start
	 * @param errorStream - A log recording object
	 */
	public void cmdReadError(final Process process, final StringJoiner errorStream, final boolean logToConsole) {
		Thread processErrorThread = new Thread(() -> {
			String line = "";
			try (BufferedReader processReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));) {
				while ((line = processReader.readLine()) != null) {
					errorStream.add(line.trim());
					if (line.contains("Error") && this.gethServerStartError.equals("Geth")) {
						this.gethServerStartError = line;
					}
					if (line.contains("IPC endpoint opened")) {// To determine
																// IPC endpoint
																// when geth
																// server is
																// started.
						this.gethIPC = line.substring(line.indexOf("url=") + 4);
					}
					if (logToConsole) {
						EthereumLogService.INSTANCE.errorLog(line);
						System.err.println(line);
					}
				}
			} catch (IOException e) {
				BlockchainCore.getInstance().logException("", e.getMessage(), e);
			}
		}, "Process Error Thread");
		processErrorThread.start();
	}
}