/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.update.tests.standalone;

import java.io.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.boot.*;
import org.eclipse.core.runtime.*;
import org.eclipse.update.configuration.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.tests.*;

public class StandaloneManagerTestCase extends UpdateManagerTestCase {
	public static StringBuffer errOutput;
	public static Integer exitValue= new Integer(-1);
	public static URL TARGET_FILE_SITE;
	private boolean oldCache = false;
	
	static {
		File targetDir = new File(System.getProperty("java.io.tmpdir"));
		targetDir = new File(targetDir, "standalone");
		targetDir = new File(targetDir, "mytarget");
		if (targetDir.exists())
			deleteDirectory(targetDir);
		try {
			TARGET_FILE_SITE = targetDir.toURL();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}
	
	public StandaloneManagerTestCase (String arg0){
		super(arg0);
	}
	
	/**
	 * Sets up the fixture, for example, open a network connection.
	 * This method is called before a test is executed.
	 */
	protected void umSetUp() {
		// setup cache site to true
		oldCache = InternalSiteManager.globalUseCache;
		InternalSiteManager.globalUseCache = true;
	}
	
	/**
	 * Tears down the fixture, for example, close a network connection.
	 * This method is called after a test is executed.
	 */
	protected void umTearDown() {
		// do nothing.
		InternalSiteManager.globalUseCache = oldCache;
	}
	
	public void checkConfiguredSites(){
		ILocalSite localSite;
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		try {
			localSite = SiteManager.getLocalSite();
			System.out.println("LocalSite: " + localSite.getCurrentConfiguration().getLabel());
		
		//Get site to install to
		IInstallConfiguration currentConfig = localSite.getCurrentConfiguration();
		IConfiguredSite[] sites = currentConfig.getConfiguredSites();
//	
//			// start of config site print
		System.out.println("GETTING CONFIGURED SITES...");
		for (int i = 0; i<sites.length; i++){
			System.out.println("site #" + i + ": " + sites[i].getSite().getURL().getFile());
		}
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		} catch (CoreException e) {
			System.err.println(e);
		}
	}
	
	// get the first configured site found because this is the one we're most likely to 
	// have installed into
	public ISite getConfiguredSite(URL target){
		try {
			ILocalSite local = SiteManager.getLocalSite();
			IInstallConfiguration currentConfig = local.getCurrentConfiguration();
			IConfiguredSite[] sites = currentConfig.getConfiguredSites();
			System.out.println("\nretrieving configured sites...");
			String targetFile = new File(target.getFile()).getAbsolutePath();
			for (int i = 0; i<sites.length ; i++){
				System.out.println("site["+i+"]: " + sites[i].getSite().getURL());
				String siteFile = new File(sites[i].getSite().getURL().getFile()).getAbsolutePath();
				if (targetFile.equals(siteFile))
					return sites[i].getSite();
			}
			if (sites.length == 0)
				return null;
			return sites[0].getSite();
		} catch (CoreException e) {
			System.err.println(e);
			return null;
		}
	}
	//WatchDog thread to kill mirroring process if it hangs (or takes too long)
	public static class Timer extends Thread{
		private Process proc;
		
		public Timer(Process proc){
			super();
			this.setDaemon(true);
			this.proc = proc;
		}
		
		public void run(){
			try {
				// sleep time 5min
				sleep(300000); 
				System.out.println("destroying process");
				proc.destroy();
			} catch (Exception e) {
				System.err.println(e);
				e.printStackTrace();
			}
		}
	}
	
	// StreamConsumer to display output to output files or console
	public static class StreamConsumer extends Thread {
		private BufferedReader bReader;

		public StreamConsumer(InputStream inputStream) {
			super();
			setDaemon(true);
			bReader = new BufferedReader(new InputStreamReader(inputStream));
			errOutput = new StringBuffer();
		}

		public void run() {
			try {
				String line;
				while (null != (line = bReader.readLine())) {
					System.err.println(line);
					errOutput.append(line);
					errOutput.append("\n");
				}
			} catch (IOException e) {
				System.err.println(e);
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * @param command : command argument to run on site/feature 
	 * (i.e. 'install', 'enable', 'disable', 'update') *<i>required</i>*
	 * @param fid : feature id of the feature being installed, enabled, etc.
	 * (optional - can be null)
	 * @param ver : version of feature being installed, enabled, etc. (optional - can be null)
	 * @param config : location of configuration info (i.e. file:D:\temp\.config\)
	 * @param remoteLoc : remote site url (required for installing/searching from remote site)
	 * @param toLocalSiteUrl : target site directory (required unless updating/searching)
	 * @return a string array consisting of commands and their arguments to
	 * be run
	 */
	public String[] getCommand(
		String command,
		String fid,
		String ver,
		String config,
		String remoteLoc,
		String localLoc){
		final String classpath = "startup.jar";
		final String launcher = "org.eclipse.core.launcher.Main";
		final String application = "org.eclipse.update.core.standaloneUpdate";
		final String FLAG_CP = "-cp";
		final String FLAG_APP = "-application";
		final String FLAG_CMD = "-command";
		final String FLAG_FID = "-featureId";
		final String FLAG_DATA = "-data";
		final String FLAG_VERSION = "-version";
		final String FLAG_FROM = "-from";
		final String FLAG_TO = "-to";
		final String FLAG_CONFIG = "-configuration";
		final String FLAG_URL = "-mirrorURL";
		final String FLAG_SPLASH = "-nosplash";
		final String FLAG_CONSOLELOG = "-consolelog";
		final String data =
			UpdateCore.getPlugin().getStateLocation().toOSString();
		String[] cmd =
			new String[] {
				getJavaVMPath(),
				FLAG_CP,
				classpath,
				launcher,
				FLAG_APP,
				application,
				FLAG_CMD,
				command,
				(remoteLoc !=null ? FLAG_FROM : ""),
				(remoteLoc !=null ? remoteLoc : ""),
				(localLoc !=null ? FLAG_TO : ""),
				(localLoc !=null ?localLoc.replaceFirst("file:", "") : ""),
				(fid != null ? FLAG_FID : ""),
				(fid != null ? fid : ""),
				(ver != null ? FLAG_VERSION : ""),
				(ver != null ? ver : ""),
				(config != null ? FLAG_CONFIG : ""),
				(config != null ? config : ""),
				FLAG_SPLASH,
				FLAG_DATA,
				data,
				FLAG_CONSOLELOG};
		for (int i = 0 ;i<cmd.length; i++){
			System.out.print(cmd[i] + " ");			
		}System.out.println();
		return cmd;
	}
	
	public String getJavaVMPath() {
		// Create command string for launching the process
		String vm = System.getProperty("java.vm.name");
		String executable = "J9".equals(vm) ? "j9" : "java";
		if (BootLoader.OS_WIN32.equals(BootLoader.getOS()))
			executable += "w.exe";

		String javaInstallDir =
			System.getProperty("java.home") + File.separator + "bin";
		return javaInstallDir + File.separator + executable;
	}
	
	public int performAction(String[] cmd) {
		File file = new File(getEclipseRoot());
		try {

			Process proc =
				Runtime.getRuntime().exec(cmd, (String[]) null, file);

			StreamConsumer outputs = new StreamConsumer(proc.getInputStream());
			outputs.start();
			StreamConsumer errors = new StreamConsumer(proc.getErrorStream());
			errors.start();
			Timer timer = new Timer(proc);
			timer.start();

			return proc.waitFor();
		} catch (IOException e) {
			System.err.println(e);
		} catch (InterruptedException e) {
			System.err.println(e);
		} catch (Exception e) {
			System.err.println(e);
		}
		return -1;
	}
	
	public String getEclipseRoot() {
		return BootLoader.getInstallURL().toExternalForm().replaceFirst(
			"file:",
			"");
	}
	
	public ArrayList getArrayList(String[] list){
		ArrayList temp = new ArrayList();
		for(int i = 0; i< list.length; i++){
			temp.add(list[i]);
		}
		return temp;
	}
	
	public File getLatestConfigurationFile(File localFile) {

		try {
			System.out.println("reading from : " + localFile.getAbsolutePath());
				FileReader freader = new FileReader(localFile);
				BufferedReader breader = new BufferedReader(freader);
				String configFileName="", line;
				while (breader.ready()) {
					line = breader.readLine();
//					System.out.println(line);
					if (line.trim().startsWith("<config url")) {
						configFileName = line.split("\"")[1];
					}
				}
				// read config file
				File parent = new File(localFile.getParent());
				System.out.println("parent: " + parent.getAbsolutePath());
				String[] parList = parent.list();
				int latest = 0; 
				for (int i = parList.length-1; i>=0; i--){
					System.out.println("parList[" + i + "]: " + parList[i]);
					if (parList[i].startsWith("platform")){
						latest = i;
						break;
					}
				}
				File configFile = new File(parent.getAbsolutePath() + File.separator + parList[latest]);
				return configFile;
				// end of config file read
		} catch (Exception e) {
			System.err.println(e);
			e.printStackTrace();
		}
		return localFile;
	}
	
	private static void deleteDirectory(File dir) {
		File[] list = dir.listFiles();
		if (list == null)
			return;
			
		for (int i=0; i<list.length; i++) {
			if (list[i].isDirectory()) 
				deleteDirectory(list[i]);
			if (!list[i].delete())
				System.out.println("Unable to delete "+list[i].toString());
		}
	}
}
