/*******************************************************************************
 * Copyright (c) 2007, 2008 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
 *     Red Hat Incorporated - fix for bug 225145
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.touchpoint.eclipse;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.*;
import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation;
import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
import org.eclipse.equinox.internal.provisional.p2.metadata.TouchpointData;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;

public class Util {

	/**
	 * TODO "cache" is probably not the right term for this location
	 */
	private final static String CONFIG_FOLDER = "eclipse.configurationFolder"; //$NON-NLS-1$
	private static final String REPOSITORY_TYPE = IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY;
	private static final String CACHE_EXTENSIONS = "org.eclipse.equinox.p2.cache.extensions"; //$NON-NLS-1$
	private static final String PIPE = "|"; //$NON-NLS-1$

	public static AgentLocation getAgentLocation() {
		return (AgentLocation) ServiceHelper.getService(Activator.getContext(), AgentLocation.class.getName());
	}

	public static IArtifactRepositoryManager getArtifactRepositoryManager() {
		return (IArtifactRepositoryManager) ServiceHelper.getService(Activator.getContext(), IArtifactRepositoryManager.class.getName());
	}

	public static URL getBundlePoolLocation(IProfile profile) {
		String path = profile.getProperty(IProfile.PROP_CACHE);
		if (path != null)
			try {
				// TODO this is a hack for now.
				return new File(path).toURL();
			} catch (MalformedURLException e) {
				// TODO Do nothing and use the default approach
			}
		AgentLocation location = getAgentLocation();
		if (location == null)
			return null;
		return location.getDataArea(Activator.ID);
	}

	static public IFileArtifactRepository getBundlePoolRepository(IProfile profile) {
		URL location = getBundlePoolLocation(profile);
		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
		try {
			return (IFileArtifactRepository) manager.loadRepository(location, null);
		} catch (ProvisionException e) {
			//the repository doesn't exist, so fall through and create a new one
		}
		try {
			String repositoryName = Messages.BundlePool;
			IArtifactRepository bundlePool = manager.createRepository(location, repositoryName, REPOSITORY_TYPE);
			manager.addRepository(bundlePool.getLocation());
			bundlePool.setProperty(IRepository.PROP_SYSTEM, Boolean.valueOf(true).toString());
			return (IFileArtifactRepository) bundlePool;
		} catch (ProvisionException e) {
			LogHelper.log(e);
			throw new IllegalArgumentException("Bundle pool repository not writeable: " + location); //$NON-NLS-1$
		}
	}

	public static IFileArtifactRepository getAggregatedBundleRepository(IProfile profile) {
		Set bundleRepositories = new HashSet();
		bundleRepositories.add(Util.getBundlePoolRepository(profile));

		IArtifactRepositoryManager manager = getArtifactRepositoryManager();
		List extensions = getListProfileProperty(profile, CACHE_EXTENSIONS);
		for (Iterator iterator = extensions.iterator(); iterator.hasNext();) {
			try {
				String extension = (String) iterator.next();
				URL extensionURL = new URL(extension);
				IArtifactRepository repository = manager.loadRepository(extensionURL, null);
				if (repository != null)
					bundleRepositories.add(repository);
			} catch (ProvisionException e) {
				//skip repositories that could not be read
			} catch (MalformedURLException e) {
				// unexpected, URLs should be pre-checked
				LogHelper.log(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
			}
		}
		return new AggregatedBundleRepository(bundleRepositories);
	}

	private static List getListProfileProperty(IProfile profile, String key) {
		List listProperty = new ArrayList();
		String dropinRepositories = profile.getProperty(key);
		if (dropinRepositories != null) {
			StringTokenizer tokenizer = new StringTokenizer(dropinRepositories, PIPE);
			while (tokenizer.hasMoreTokens()) {
				listProperty.add(tokenizer.nextToken());
			}
		}
		return listProperty;
	}

	public static BundleInfo createBundleInfo(File bundleFile, String manifest) {
		BundleInfo bundleInfo = new BundleInfo();
		try {
			if (bundleFile != null)
				bundleInfo.setLocation(bundleFile.toURL().toExternalForm());
		} catch (MalformedURLException e) {
			//Ignore since we are creating the URL from the file
		}

		bundleInfo.setManifest(manifest);
		try {
			Headers headers = Headers.parseManifest(new ByteArrayInputStream(manifest.getBytes()));
			ManifestElement[] element = ManifestElement.parseHeader("bsn", (String) headers.get(Constants.BUNDLE_SYMBOLICNAME)); //$NON-NLS-1$
			if (element == null || element.length == 0)
				return null;
			bundleInfo.setSymbolicName(element[0].getValue());

			String version = (String) headers.get(Constants.BUNDLE_VERSION);
			if (version == null)
				return null;
			bundleInfo.setVersion(version);
		} catch (BundleException e) {
			// unexpected
			LogHelper.log(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
			return null;
		}
		return bundleInfo;
	}

	public static File getArtifactFile(IArtifactKey artifactKey, IProfile profile) {
		IFileArtifactRepository aggregatedView = getAggregatedBundleRepository(profile);
		File bundleJar = aggregatedView.getArtifactFile(artifactKey);
		return bundleJar;
	}

	public static File getConfigurationFolder(IProfile profile) {
		String config = profile.getProperty(CONFIG_FOLDER);
		if (config != null)
			return new File(config);
		return new File(getInstallFolder(profile), "configuration"); //$NON-NLS-1$
	}

	public static File getInstallFolder(IProfile profile) {
		return new File(profile.getProperty(IProfile.PROP_INSTALL_FOLDER));
	}

	public static File getLauncherPath(IProfile profile) {
		return new File(getInstallFolder(profile), getLauncherName(profile));
	}

	/**
	 * Returns the name of the Eclipse application launcher.
	 */
	private static String getLauncherName(IProfile profile) {
		String name = profile.getProperty(EclipseTouchpoint.PROFILE_PROP_LAUNCHER_NAME);

		String os = getOSFromProfile(profile);
		if (os == null) {
			EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName());
			if (info != null)
				os = info.getOS();
		}
		if (name == null)
			name = "eclipse"; //$NON-NLS-1$

		if (os.equals(org.eclipse.osgi.service.environment.Constants.OS_MACOSX)) {
			return name + ".app/Contents/MacOS/" + name.toLowerCase(); //$NON-NLS-1$
		}
		return name;
	}

	private static String getOSFromProfile(IProfile profile) {
		String environments = profile.getProperty(IProfile.PROP_ENVIRONMENTS);
		if (environments == null)
			return null;
		for (StringTokenizer tokenizer = new StringTokenizer(environments, ","); tokenizer.hasMoreElements();) { //$NON-NLS-1$
			String entry = tokenizer.nextToken();
			int i = entry.indexOf('=');
			String key = entry.substring(0, i).trim();
			if (!key.equals("osgi.os")) //$NON-NLS-1$
				continue;
			return entry.substring(i + 1).trim();
		}
		return null;
	}

	public static String getManifest(TouchpointData[] data) {
		for (int i = 0; i < data.length; i++) {
			String manifest = data[i].getInstructions("manifest"); //$NON-NLS-1$
			if (manifest != null && manifest.length() > 0)
				return manifest;
		}
		return null;
	}

	/**
	 * Returns the agent location, if possible as a path relative to the configuration
	 * directory using the @config.dir substitution variable. AgentLocation will
	 * substitute this variable with the configuration folder location on startup.
	 * If the agent location is not a sub-directory of the configuration folder, this
	 * method simply returns the absolute agent location expressed as a URL.
	 */
	public static String computeRelativeAgentLocation(IProfile profile) {
		URL agentURL = Util.getAgentLocation().getURL();
		//TODO handle proper path/url conversion
		IPath agentPath = new Path(agentURL.getPath());
		IPath configPath = new Path(Util.getConfigurationFolder(profile).getAbsolutePath());
		if (configPath.isPrefixOf(agentPath))
			return "@config.dir/" + agentPath.removeFirstSegments(configPath.segmentCount()).makeRelative().setDevice(null); //$NON-NLS-1$
		if (agentPath.removeLastSegments(1).equals(configPath.removeLastSegments(1)))
			return "@config.dir/../" + agentPath.lastSegment(); //$NON-NLS-1$
		return agentURL.toString();
	}

	public static IStatus createError(String message) {
		return createError(message, null);
	}

	public static IStatus createError(String message, Exception e) {
		return new Status(IStatus.ERROR, Activator.ID, message, e);
	}

}
