package fr.inria.arles.yarta.desktop.library.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLConnection;
import javax.swing.JOptionPane;
import fr.inria.arles.yarta.desktop.library.DownloaderDialog;
import fr.inria.arles.yarta.desktop.library.RMIUtil;
import fr.inria.arles.yarta.desktop.library.Service;
/**
 * Helper class which permits (un)installing & updating the application.
 */
public class Installer {
	public static final String InstallPath = System.getProperty("user.home")
			+ "/.yarta/";
	public static final String FilesPath = InstallPath + "res/";
	private static final String[] files = { "mse-1.2.rdf", "policies" };
	private String currentJarPath;
	private String installedJarPath;
	private Exception error;
	public Installer() {
		String jarFile = System.getProperty("java.class.path");
		if (!jarFile.endsWith("jar")) {
			jarFile = "yarta.jar";
		}
		currentJarPath = new File(jarFile).getAbsolutePath();
		installedJarPath = InstallPath + "yarta.jar";
	}
	/**
	 * Checks whether Yarta is installed on the current machine.
	 * 
	 * @return
	 */
	public boolean isInstalled() {
		return checkFilesConsistency();
	}
	/**
	 * Checks if Yarta Service is running.
	 * 
	 * @return
	 */
	public boolean isRunning() {
		Service service = RMIUtil.getObject(Service.Name);
		boolean running = service != null;
		service = null;
		return running;
	}
	/**
	 * Runs a jar file with the specified arguments;
	 * 
	 * @param jarPath
	 * @param args
	 * @return
	 */
	private Process runJar(String jarPath, String... args) {
		String command = "java -jar " + jarPath;
		if (isWindows()) {
			command = "javaw -jar " + jarPath;
		}
		for (String arg : args) {
			command += " " + arg;
		}
		try {
			return Runtime.getRuntime().exec(command);
		} catch (Exception ex) {
		}
		return null;
	}
	/**
	 * Launches the application.
	 * 
	 * @return
	 */
	public boolean launchApp() {
		return runJar(installedJarPath) != null;
	}
	/**
	 * Returns the timestamp of yarta.jar from Internet.
	 * 
	 * @return
	 */
	private long getLastModifiedRemote() {
		long lastModified = 0;
		try {
			URL url = new URL(Strings.DownloaderYartaLink);
			URLConnection conn = url.openConnection();
			lastModified = conn.getLastModified();
		} catch (Exception ex) {
		}
		return lastModified;
	}
	/**
	 * Checks for updates, and if there are any, asks users and update. Returns
	 * false otherwise.
	 * 
	 * @return true/false
	 */
	public boolean checkAndUpdate() {
		long lastModifiedLocal = new File(installedJarPath).lastModified();
		long lastModifiedRemote = getLastModifiedRemote();
		if (lastModifiedRemote > lastModifiedLocal) {
			int option = 0;
			try {
				option = JOptionPane.showConfirmDialog(null,
						Strings.InstallerUpdatePrompt,
						Strings.InstallerUpdateTitle,
						JOptionPane.OK_CANCEL_OPTION,
						JOptionPane.INFORMATION_MESSAGE);
			} catch (Exception ex) {
				// system does not have UI
				option = JOptionPane.OK_OPTION;
			}
			if (option == JOptionPane.OK_OPTION) {
				String downloadedJarFile = performDownload();
				if (downloadedJarFile != null) {
					return performInstallerLaunch(downloadedJarFile);
				}
			}
		}
		return false;
	}
	public boolean launchService() {
		return runJar(installedJarPath, "/start") != null;
	}
	public boolean stopService() {
		if (!new File(installedJarPath).exists()) {
			return true;
		}
		try {
			Process process = runJar(installedJarPath, "/stop");
			process.waitFor();
			return true;
		} catch (Exception ex) {
			return false;
		}
	}
	public boolean install() {
		boolean hasUI = true;
		try {
			int selection = JOptionPane.showConfirmDialog(null,
					Strings.InstallerPrompt, Strings.InstallerPromptTitle,
					JOptionPane.OK_CANCEL_OPTION,
					JOptionPane.INFORMATION_MESSAGE);
			if (selection == JOptionPane.OK_OPTION) {
				return performInstallation();
			}
		} catch (Exception ex) {
			hasUI = false;
		}
		if (!hasUI) {
			return performInstallation();
		}
		return false;
	}
	/**
	 * This should download and install Yarta.
	 * 
	 * When the function returns true Yarta will be installed.
	 * 
	 * @return true/false
	 */
	public boolean downloadAndInstall() {
		int selection = JOptionPane.showConfirmDialog(null,
				Strings.InstallerDownloadPrompt,
				Strings.InstallerDownloadTitle, JOptionPane.OK_CANCEL_OPTION,
				JOptionPane.INFORMATION_MESSAGE);
		if (selection == JOptionPane.OK_OPTION) {


Answer: 			String downloadedJarFile = performDownload();