/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.presentation.dependency;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.file.Files;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Shell;

import com.refactorerl.ui.common.Environment;

//linux: $ type -a dot
public class GraphvizSupport {
	/** beware, this is sync op*/
	public static File createSVG(Shell shell, String dotContents)
			throws IOException {
		String dotName = Environment.isLocalSysWindows() ? "dot.exe" : "dot"; //$NON-NLS-1$ //$NON-NLS-2$
		
		IEclipsePreferences prefs = InstanceScope.INSTANCE
				.getNode("com.refactorerl.ui"); //$NON-NLS-1$
		String dotExecPath = prefs.get("path_to_dot_executable", null); //$NON-NLS-1$

		if (dotExecPath == null || !isDotPathValid(dotName, dotExecPath)) {
			DirectoryDialog dialog = new DirectoryDialog(shell);
			dialog.setText(Messages.GraphvizSupport_2);
			dialog.setMessage(Messages.GraphvizSupport_3);

			do {
				dotExecPath = null;
				dotExecPath = dialog.open();
				if (dotExecPath == null)
					return null;

				if (isDotPathValid(dotName, dotExecPath))
					break;

				MessageDialog
						.openWarning(shell, Messages.GraphvizSupport_5,
								Messages.GraphvizSupport_6);

			} while (true);

			prefs.put("path_to_dot_executable", dotExecPath); //$NON-NLS-1$
		}
		File tmpDir = Environment.getTempDir();
		File inputFile = File.createTempFile("dotinput", ".dot", tmpDir); //$NON-NLS-1$ //$NON-NLS-2$
		PrintWriter pw = new PrintWriter(inputFile);
		pw.print(dotContents);
		pw.println();
		pw.flush();
		pw.close();

		File outputFile = File.createTempFile("dotresult", ".svg", tmpDir); //$NON-NLS-1$ //$NON-NLS-2$

		ProcessBuilder pb = new ProcessBuilder(dotName, "-Tsvg", //$NON-NLS-1$ //$NON-NLS-2$
				inputFile.getAbsolutePath(), "-o", outputFile.getAbsolutePath()); //$NON-NLS-1$
		pb.directory(new File(dotExecPath));
		if(Environment.isLocalSysWindows()){
			pb = new ProcessBuilder(dotExecPath + File.separator + dotName, "-Tsvg", //$NON-NLS-1$ //$NON-NLS-2$
					inputFile.getAbsolutePath(), "-o", outputFile.getAbsolutePath()); //$NON-NLS-1$
		}
		
		Process p = pb.start();
		BufferedReader outReader = 
                new BufferedReader(new InputStreamReader(p.getInputStream()));
		BufferedReader errReader = 
                new BufferedReader(new InputStreamReader(p.getErrorStream()));
		
		try {
			p.waitFor();
		} catch (InterruptedException e) {
			System.out.println(Messages.GraphvizSupport_14);
			return outputFile;
		}
		
		String outResult = bufferedReader2String(outReader);
		String errResult = bufferedReader2String(errReader);
		if(!outResult.isEmpty())
			MessageDialog.openInformation(shell, Messages.GraphvizSupport_8, outResult);
		if(!errResult.isEmpty())
			MessageDialog.openError(shell, Messages.GraphvizSupport_9, errResult);
		
		return outputFile;

	}

	private static String bufferedReader2String(BufferedReader outReader)
			throws IOException {
		StringBuilder builder = new StringBuilder();
		String line = null;
		while ( (line = outReader.readLine()) != null) {
		   builder.append(line);
		   builder.append(System.getProperty("line.separator")); //$NON-NLS-1$
		}
		String result = builder.toString();
		return result;
	}

	private static boolean isDotPathValid(String dotName, String dotExecPath) {
		File dotExec = new File(dotExecPath + File.separator + dotName); //$NON-NLS-1$
		boolean dotValid = dotExec.exists() && dotExec.isFile()
				&& dotExec.canExecute();
		return dotValid;
	}

	public static File createSVG(Shell shell, String dotContents,
			String targetDirectory, String fileName) throws IOException {

		File tmp = createSVG(shell, dotContents);
		if (tmp == null)
			return null;

		final File target = new File(targetDirectory + File.separator
				+ fileName + (fileName.endsWith(".svg") ? "" : ".svg")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		Files.copy(tmp.toPath(), target.toPath()); 

		return target;
	}

}
