/*******************************************************************************
 *  Copyright (c) 2007, 2017 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
 *      Ericsson AB - Bug 400011 - [shared] Cleanup the SurrogateProfileHandler code
 *      Red Hat, Inc. - fragments support added., Bug 460967
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.engine;

import java.io.File;
import java.lang.ref.SoftReference;
import java.net.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.IRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.util.NLS;

public class SurrogateProfileHandler implements ISurrogateProfileHandler {

	private static final String NATIVE_TOUCHPOINT_TYPE = "org.eclipse.equinox.p2.native"; //$NON-NLS-1$
	private static final String P2_ENGINE_DIR = "p2/" + EngineActivator.ID + "/"; //$NON-NLS-1$//$NON-NLS-2$
	private static final String OSGI_INSTALL_AREA = "osgi.install.area"; //$NON-NLS-1$
	private static final String ECLIPSE_INI_IGNORED = "eclipse.ini.ignored"; //$NON-NLS-1$
	private static final String IU_LOCKED = Integer.toString(IProfile.LOCK_UNINSTALL | IProfile.LOCK_UPDATE);
	private static final String PROP_SURROGATE = "org.eclipse.equinox.p2.surrogate"; //$NON-NLS-1$
	private static final String PROP_BASE = "org.eclipse.equinox.p2.base"; //$NON-NLS-1$
	private static final String STRICT = "STRICT"; //$NON-NLS-1$
	private static final String PROP_INCLUSION_RULES = "org.eclipse.equinox.p2.internal.inclusion.rules"; //$NON-NLS-1$

	private final IProvisioningAgent agent;

	private SimpleProfileRegistry profileRegistry;

	private SoftReference<IProfile> cachedProfile;

	private static void addSharedProfileBaseIUs(final IProfile sharedProfile, final Profile userProfile) {
		IQuery<IInstallableUnit> rootIUQuery = QueryUtil.createMatchQuery( //
				"profileProperties[$0] == 'true' || (touchpointType != null && touchpointType.id == $1)", //$NON-NLS-1$
				IProfile.PROP_PROFILE_ROOT_IU, NATIVE_TOUCHPOINT_TYPE);
		IQueryResult<IInstallableUnit> rootIUs = sharedProfile.query(rootIUQuery, null);
		for (Iterator<IInstallableUnit> iterator = rootIUs.iterator(); iterator.hasNext();) {
			IInstallableUnit iu = iterator.next();
			userProfile.addInstallableUnit(iu);
			userProfile.addInstallableUnitProperties(iu, sharedProfile.getInstallableUnitProperties(iu));
			userProfile.setInstallableUnitProperty(iu, IProfile.PROP_PROFILE_LOCKED_IU, IU_LOCKED);
			userProfile.setInstallableUnitProperty(iu, PROP_BASE, Boolean.TRUE.toString());
		}

		IInstallableUnit sharedProfileIU = createSharedProfileIU(sharedProfile);
		userProfile.addInstallableUnit(sharedProfileIU);
		userProfile.setInstallableUnitProperty(sharedProfileIU, PROP_INCLUSION_RULES, STRICT);
		userProfile.setInstallableUnitProperty(sharedProfileIU, PROP_BASE, Boolean.TRUE.toString());
	}

	private static IInstallableUnit createSharedProfileIU(final IProfile sharedProfile) {
		InstallableUnitDescription iuDescription = new InstallableUnitDescription();
		iuDescription.setId("SharedProfile_" + sharedProfile.getProfileId()); //$NON-NLS-1$
		iuDescription.setVersion(Version.createOSGi(1, 0, 0, Long.toString(sharedProfile.getTimestamp())));

		ArrayList<IProvidedCapability> iuCapabilities = new ArrayList<>();
		IProvidedCapability selfCapability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, iuDescription.getId(), iuDescription.getVersion());
		iuCapabilities.add(selfCapability);
		iuDescription.addProvidedCapabilities(iuCapabilities);

		ArrayList<IRequirement> iuRequirements = new ArrayList<>();
		IQueryResult<IInstallableUnit> allIUs = sharedProfile.query(QueryUtil.createIUAnyQuery(), null);
		for (Iterator<IInstallableUnit> iterator = allIUs.iterator(); iterator.hasNext();) {
			IInstallableUnit iu = iterator.next();
			IMatchExpression<IInstallableUnit> iuMatcher = ExpressionUtil.getFactory().<IInstallableUnit> matchExpression(ExpressionUtil.parse("id == $0 && version == $1"), iu.getId(), iu.getVersion()); //$NON-NLS-1$
			iuRequirements.add(MetadataFactory.createRequirement(iuMatcher, null, 0, 1, true));
		}
		iuDescription.addRequirements(iuRequirements);
		iuDescription.setProperty(IInstallableUnit.PROP_NAME, NLS.bind(Messages.Shared_Profile, null));

		IInstallableUnit sharedProfileIU = MetadataFactory.createInstallableUnit(iuDescription);
		return sharedProfileIU;
	}

	private static void updateProperties(final IProfile sharedProfile, Profile userProfile) {
		Location installLocation = ServiceHelper.getService(EngineActivator.getContext(), Location.class, Location.INSTALL_FILTER);
		File installFolder = new File(installLocation.getURL().getPath());

		if (Boolean.parseBoolean(sharedProfile.getProperty(IProfile.PROP_ROAMING))) {
			userProfile.setProperty(IProfile.PROP_INSTALL_FOLDER, installFolder.getAbsolutePath());
			userProfile.setProperty(IProfile.PROP_SHARED_CACHE, installFolder.getAbsolutePath());
			userProfile.setProperty(IProfile.PROP_ROAMING, Boolean.FALSE.toString());
		} else {
			String cache = sharedProfile.getProperty(IProfile.PROP_CACHE);
			if (cache != null)
				userProfile.setProperty(IProfile.PROP_SHARED_CACHE, cache);
		}

		Location configurationLocation = ServiceHelper.getService(EngineActivator.getContext(), Location.class, Location.CONFIGURATION_FILTER);
		File configurationFolder = new File(configurationLocation.getURL().getPath());
		userProfile.setProperty(IProfile.PROP_CONFIGURATION_FOLDER, configurationFolder.getAbsolutePath());

		// We need to check that the configuration folder is not a file system root. 
		// some of the profiles resources are stored as siblings to the configuration folder.
		// also see bug 230384
		if (configurationFolder.getParentFile() == null)
			throw new IllegalArgumentException("Configuration folder must not be a file system root."); //$NON-NLS-1$

		userProfile.setProperty(IProfile.PROP_CACHE, configurationFolder.getParentFile().getAbsolutePath());

		File launcherConfigFile = new File(configurationFolder, ECLIPSE_INI_IGNORED);
		userProfile.setProperty(IProfile.PROP_LAUNCHER_CONFIGURATION, launcherConfigFile.getAbsolutePath());
	}

	public SurrogateProfileHandler(IProvisioningAgent agent) {
		this.agent = agent;
	}

	private synchronized SimpleProfileRegistry getProfileRegistry() {
		if (profileRegistry == null) {
			String installArea = EngineActivator.getContext().getProperty(OSGI_INSTALL_AREA);
			try {
				URL registryURL = new URL(installArea + P2_ENGINE_DIR + SimpleProfileRegistry.DEFAULT_STORAGE_DIR);
				File sharedRegistryDirectory = URIUtil.toFile(URIUtil.toURI(registryURL));
				profileRegistry = new SimpleProfileRegistry(agent, sharedRegistryDirectory, null, false);
			} catch (MalformedURLException e) {
				//this is not possible because we know the above URL is valid
			} catch (URISyntaxException e) {
				//this is not possible because we know the above URL is valid
			}
		}
		return profileRegistry;
	}

	// this method must not try to lock the profile registry
	private IProfile getSharedProfile(String id) {
		SimpleProfileRegistry registry = getProfileRegistry();
		long[] timestamps = registry.listProfileTimestamps(id);
		if (timestamps.length == 0)
			return null;

		long currentTimestamp = timestamps[timestamps.length - 1];

		//see if we have a cached profile
		if (cachedProfile != null) {
			IProfile profile = cachedProfile.get();
			if (profile != null && profile.getProfileId().equals(id) && profile.getTimestamp() == currentTimestamp)
				return profile;
		}

		final Profile profile = (Profile) registry.getProfile(id, currentTimestamp);
		if (profile != null)
			cachedProfile = new SoftReference<IProfile>(profile);

		if (!EngineActivator.EXTENDED) {
			return profile;
		}

		setUpRepos();
		return profile;
	}

	/**
	 * Removes repositories from fragments locations as they might be obsolete and adds them back.
	 */
	private void setUpRepos() {
		//clean old junk
		IMetadataRepositoryManager metaManager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
		URI[] knownRepositories = metaManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_LOCAL);
		for (URI uri : knownRepositories) {
			if ("true".equals(metaManager.getRepositoryProperty(uri, EngineActivator.P2_FRAGMENT_PROPERTY))) { //$NON-NLS-1$
				metaManager.removeRepository(uri);
			}
		}

		IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) agent.getService(IArtifactRepositoryManager.SERVICE_NAME);
		knownRepositories = artifactManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_LOCAL);
		for (URI uri : knownRepositories) {
			if ("true".equals(artifactManager.getRepositoryProperty(uri, EngineActivator.P2_FRAGMENT_PROPERTY))) { //$NON-NLS-1$
				artifactManager.removeRepository(uri);
			}
		}

		File[] fragments = EngineActivator.getExtensionsDirectories();
		for (File f : fragments) {
			metaManager.addRepository(f.toURI());
			metaManager.setRepositoryProperty(f.toURI(), EngineActivator.P2_FRAGMENT_PROPERTY, Boolean.TRUE.toString());
			artifactManager.addRepository(f.toURI());
			artifactManager.setRepositoryProperty(f.toURI(), EngineActivator.P2_FRAGMENT_PROPERTY, Boolean.TRUE.toString());
		}
	}

	@Override
	public IProfile createProfile(String id) {
		final Profile sharedProfile = (Profile) getSharedProfile(id);
		if (sharedProfile == null)
			return null;

		if (!EngineActivator.EXTENDED) {
			Profile userProfile = new Profile(agent, id, null, sharedProfile.getProperties());
			userProfile.setProperty(PROP_SURROGATE, Boolean.TRUE.toString());
			userProfile.setSurrogateProfileHandler(this);
			updateProperties(sharedProfile, userProfile);
			addSharedProfileBaseIUs(sharedProfile, userProfile);

			return userProfile;
		}

		File[] extensionLocations = EngineActivator.getExtensionsDirectories();
		Set<IInstallableUnit> added = new HashSet<>();
		for (File extension : extensionLocations) {
			try {
				IMetadataRepositoryManager metaManager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
				IMetadataRepository repo = metaManager.loadRepository(extension.toURI(), new NullProgressMonitor());
				Set<IInstallableUnit> installableUnits = repo.query(QueryUtil.createIUAnyQuery(), new NullProgressMonitor()).toUnmodifiableSet();
				for (IInstallableUnit unit : installableUnits) {
					Collection<IProvidedCapability> capabilities = unit.getProvidedCapabilities();
					boolean featureOrBundle = false;
					for (IProvidedCapability cap : capabilities) {
						if ("org.eclipse.equinox.p2.eclipse.type".equals(cap.getNamespace())) { //$NON-NLS-1$
							if ("bundle".equals(cap.getName()) //$NON-NLS-1$
									|| "source".equals(cap.getName()) //$NON-NLS-1$
									|| "feature".equals(cap.getName())) { //$NON-NLS-1$
								featureOrBundle = true;
							}
						} else if (Boolean.TRUE.equals(Boolean.valueOf(unit.getProperties().get("org.eclipse.equinox.p2.type.group")))) { //$NON-NLS-1$
							featureOrBundle = true;
						}
					}
					if (featureOrBundle && !added.contains(unit)) {
						added.add(unit);
						sharedProfile.addInstallableUnit(unit);
					}

					Map<String, String> iuProperties = unit.getProperties();
					if (iuProperties != null && !iuProperties.isEmpty()) {
						sharedProfile.addInstallableUnitProperties(unit, iuProperties);
					}
				}
			} catch (ProvisionException e) {
				LogHelper.log(new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.SurrogateProfileHandler_1, extension), e));
			}
		}

		Profile userProfile = new Profile(agent, id, null, sharedProfile.getProperties());
		userProfile.setProperty(PROP_SURROGATE, Boolean.TRUE.toString());
		userProfile.setSurrogateProfileHandler(this);
		updateProperties(sharedProfile, userProfile);
		addSharedProfileBaseIUs(sharedProfile, userProfile);

		return userProfile;
	}

	@Override
	public boolean isSurrogate(IProfile profile) {
		return Boolean.parseBoolean(profile.getProperty(PROP_SURROGATE));
	}

	@Override
	public IQueryResult<IInstallableUnit> queryProfile(IProfile profile, IQuery<IInstallableUnit> query, IProgressMonitor monitor) {
		IProfile sharedProfile = getSharedProfile(profile.getProfileId());
		if (sharedProfile == null)
			return profile.query(query, monitor);

		// TODO: Should consider using a sequenced iterator here instead of collecting
		Collector<IInstallableUnit> result = new Collector<>();
		result.addAll(sharedProfile.query(query, monitor));
		result.addAll(profile.query(query, monitor));
		return result;
	}
}
