/*=============================================================================#
 # Copyright (c) 2016, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.jcommons.rmi.eplatform;

import static org.eclipse.statet.internal.jcommons.rmi.CommonsRmiInternals.BUNDLE_ID;

import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.RegistryFactory;

import org.eclipse.statet.internal.jcommons.runtime.eplatform.EPlatformAppEnvironment;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
import org.eclipse.statet.jcommons.status.MultiStatus;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.eplatform.EStatusUtils;


@NonNullByDefault
public class EPlatformContributor {
	
	
	private static final String EXTENSIONPOINT_ID= "org.eclipse.statet.jcommons.rmi.ERegistry"; //$NON-NLS-1$
	
	private static void log(final IStatus status) {
		Platform.getLog(Platform.getBundle(BUNDLE_ID)).log(status);
	}
	
	
	public EPlatformContributor() {
	}
	
	
	public List<URI> addCodebaseEntries(final List<URI> entries) {
		final LinkedHashSet<BundleEntry> resolved= new LinkedHashSet<>();
		final List<Status> statusCollector= new ArrayList<>();
		
		final List<String> pluginIds= collectPluginIds(EXTENSIONPOINT_ID, "codebaseEntry"); //$NON-NLS-1$
		
		final EPlatformAppEnvironment appEnv= EPlatformAppEnvironment.getInstance();
		for (final String pluginId : pluginIds) {
			appEnv.resolveBundle(new BundleSpec(pluginId), resolved, statusCollector);
		}
		for (final BundleEntry entry : resolved) {
			entries.add(entry.getJClassPath().toUri());
		}
		
		if (!statusCollector.isEmpty()) {
			log(EStatusUtils.convert(new MultiStatus(BUNDLE_ID,
					"An error occurred when looking up RJ libraries. This may cause problems starting/running RJ.",
					null,
					ImCollections.toList(statusCollector) )));
		}
		return entries;
	}
	
	private List<String> collectPluginIds(final String extensionPointId, final String entryId) {
		final var configurationElements= RegistryFactory.getRegistry()
				.getConfigurationElementsFor(extensionPointId);
		final List<String> pluginIds= new ArrayList<>();
		for (final IConfigurationElement element : configurationElements) {
			if (element.getName().equals(entryId)) {
				final String pluginId= element.getAttribute("pluginId"); //$NON-NLS-1$
				if (pluginId != null && pluginId.length() > 0
						&& !pluginIds.contains(pluginId)) {
					pluginIds.add(pluginId);
				}
			}
		}
		return pluginIds;
	}
	
}
