/*******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.tests.session;

import java.io.*;
import java.net.URL;
import java.util.*;
import junit.framework.*;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.tests.harness.CoreTest;
import org.eclipse.core.tests.harness.FileSystemHelper;
import org.eclipse.core.tests.session.SetupManager.SetupException;
import org.eclipse.osgi.service.datalocation.Location;
import org.osgi.framework.Bundle;

public class ConfigurationSessionTestSuite extends SessionTestSuite {
	// include configurator as it is required by compatibility, but do not set it to start 	
	public static String[] MINIMAL_BUNDLE_SET = {
		// -- new portion:
		"org.eclipse.equinox.common@2:start", 
		"org.eclipse.core.jobs@2:start", 
		"org.eclipse.core.runtime.compatibility.registry",
		"org.eclipse.equinox.registry@2:start", 
		"org.eclipse.equinox.preferences", 
		"org.eclipse.core.contenttype",
		"org.eclipse.equinox.app@2",
		// -- end of new
		"org.eclipse.core.runtime@2:start", 
		"org.eclipse.core.runtime.compatibility", 
		"org.eclipse.core.runtime.compatibility.auth", 
		"org.eclipse.update.configurator", 
		"org.eclipse.core.tests.harness", 
		"org.eclipse.jdt.junit.runtime", 
		"org.eclipse.pde.junit.runtime", 
		"org.junit", 
		"org.eclipse.test.performance"
		};

	private static final String PROP_CONFIG_AREA_READ_ONLY = InternalPlatform.PROP_CONFIG_AREA + ".readOnly";
	private static final String PROP_CONFIG_CASCADED = "osgi.configuration.cascaded";
	private static final String PROP_SHARED_CONFIG_AREA = "osgi.sharedConfiguration.area";
	private Collection bundles = new ArrayList();
	private boolean cascaded;

	// by default we clean-up after ourselves
	private boolean cleanUp = true;

	private IPath configurationPath = FileSystemHelper.getRandomLocation(FileSystemHelper.getTempDir());
	private boolean prime = true;
	private boolean readOnly;
	// should the test cases be run in alphabetical order?
	private boolean shouldSort;

	public ConfigurationSessionTestSuite(String pluginId) {
		super(pluginId);
	}

	public ConfigurationSessionTestSuite(String pluginId, Class theClass) {
		super(pluginId, theClass);
		this.shouldSort = true;
	}

	public ConfigurationSessionTestSuite(String pluginId, Class theClass, String name) {
		super(pluginId, theClass, name);
		this.shouldSort = true;
	}

	public ConfigurationSessionTestSuite(String pluginId, String name) {
		super(pluginId, name);
	}

	public void addBundle(String id) {
		bundles.add(getURL(id));
	}

	private void createConfigINI() throws IOException {
		Assert.assertTrue("1.0", !bundles.isEmpty());
		Properties contents = new Properties();
		StringBuffer osgiBundles = new StringBuffer();
		for (Iterator i = this.bundles.iterator(); i.hasNext();) {
			osgiBundles.append(i.next());
			osgiBundles.append(',');
		}
		osgiBundles.deleteCharAt(osgiBundles.length() - 1);
		contents.put("osgi.bundles", osgiBundles.toString());
		String osgiFramework = getURL("org.eclipse.osgi");
		contents.put("osgi.framework", osgiFramework);
		contents.put("osgi.bundles.defaultStartLevel", "4");
		contents.put("osgi.install.area", Platform.getInstallLocation().getURL().toExternalForm());
		contents.put(PROP_CONFIG_CASCADED, Boolean.toString(cascaded));
		if (cascaded)
			contents.put(PROP_SHARED_CONFIG_AREA, Platform.getConfigurationLocation().getURL().toExternalForm());
		contents.put(PROP_CONFIG_AREA_READ_ONLY, Boolean.toString(readOnly));
		// save the properties
		File configINI = configurationPath.append("config.ini").toFile();
		OutputStream out = null;
		try {
			out = new BufferedOutputStream(new FileOutputStream(configINI));
			contents.store(out, null);
		} finally {
			if (out != null)
				out.close();
		}
	}

	protected void fillTestDescriptor(TestDescriptor test) throws SetupException {
		super.fillTestDescriptor(test);
		if (prime) {
			test.getSetup().setSystemProperty(PROP_CONFIG_AREA_READ_ONLY, Boolean.FALSE.toString());
			prime = false;
		}
	}

	public IPath getConfigurationPath() {
		return configurationPath;
	}

	private String getURL(String id) {
		String suffix = "";
		int atIndex = id.indexOf("@");
		if (atIndex >= 0) {
			suffix = id.substring(atIndex);
			id = id.substring(0, atIndex);
		}
		Bundle bundle = Platform.getBundle(id);
		Assert.assertNotNull("0.1 " + id, bundle);
		URL url = bundle.getEntry("/");
		Assert.assertNotNull("0.2 " + id, url);
		try {
			url = Platform.resolve(url);
		} catch (IOException e) {
			CoreTest.fail("0.3 " + url, e);
		}
		String externalForm;
		if (url.getProtocol().equals("jar")) {
			// if it is a JAR'd plug-in, URL is jar:file:/path/file.jar!/ - see bug 86195
			String path = url.getPath();
			// change it to be file:/path/file.jar
			externalForm = path.substring(0, path.length() - 2);
		} else
			externalForm = url.toExternalForm();
		// workaround for bug 88070		
		externalForm = "reference:" + externalForm;
		return externalForm + suffix;
	}

	public boolean isCascaded() {
		return cascaded;
	}

	public boolean isReadOnly() {
		return readOnly;
	}

	/**
	 * Ensures setup uses this suite's instance location.
	 * @throws SetupException
	 */
	protected Setup newSetup() throws SetupException {
		Setup base = super.newSetup();
		// the base implementation will have set this to the host configuration
		base.setEclipseArgument(Setup.CONFIGURATION, null);
		base.setSystemProperty(InternalPlatform.PROP_CONFIG_AREA, configurationPath.toOSString());
		return base;
	}

	/**
	 * Ensures workspace location is empty before running the first test, and after
	 * running the last test. Also sorts the test cases to be run if this suite was
	 * created by reifying a test case class.
	 */
	public void run(TestResult result) {
		configurationPath.toFile().mkdirs();
		try {
			if (prime)
				try {
					createConfigINI();
				} catch (IOException e) {
					CoreTest.fail("0.1", e);
				}
			if (!shouldSort || isSharedSession()) {
				// for shared sessions, we don't control the execution of test cases
				super.run(result);
				return;
			}
			// we have to sort the tests cases
			Test[] allTests = getTests(true);
			// now run the tests in order			
			for (int i = 0; i < allTests.length && !result.shouldStop(); i++)
				runTest(allTests[i], result);
		} finally {
			if (cleanUp)
				FileSystemHelper.clear(configurationPath.toFile());
		};

	}

	public void setCascaded(boolean cascaded) {
		this.cascaded = cascaded;
	}

	public void setCleanup(boolean cleanUp) {
		this.cleanUp = cleanUp;
	}

	public void setConfigurationPath(IPath configurationPath) {
		this.configurationPath = configurationPath;
	}

	public void setPrime(boolean prime) {
		this.prime = prime;
	}

	public void setReadOnly(boolean readOnly) {
		this.readOnly = readOnly;
	}

	public static File getConfigurationDir() {
		Location configurationLocation = Platform.getConfigurationLocation();
		URL configurationURL = configurationLocation.getURL();
		if (!"file".equals(configurationURL.getProtocol()))
			// only works if configuration is file: based
			throw new IllegalStateException();
		File configurationDir = new File(configurationURL.getFile());
		return configurationDir;
	}

}
