/*******************************************************************************
 * Copyright (c) 2005, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.metatype.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.equinox.metatype.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.cm.ManagedServiceFactory;
import org.osgi.service.metatype.*;
import org.osgi.util.tracker.ServiceTracker;

public class MetaTypeProviderTracker implements EquinoxMetaTypeInformation {
	private final Bundle _bundle;
	private final LogTracker log;
	private final ServiceTracker<Object, Object> _tracker;

	/**
	 * Constructs a MetaTypeProviderTracker which tracks all MetaTypeProviders
	 * registered by the specified bundle.
	 * @param context The BundleContext of the MetaTypeService implementation
	 * @param bundle The bundle to track all MetaTypeProviders for.
	 * @param log The {@code LogService} to use for logging messages.
	 */
	public MetaTypeProviderTracker(Bundle bundle, LogTracker log, ServiceTracker<Object, Object> tracker) {
		this._bundle = bundle;
		this._tracker = tracker;
		this.log = log;
	}

	private String[] getPids(boolean factory) {
		if (_bundle.getState() != Bundle.ACTIVE)
			return new String[0]; // return none if not active
		MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
		ArrayList<String> results = new ArrayList<String>();
		for (int i = 0; i < wrappers.length; i++) {
			// return only the correct type of pids (regular or factory)
			if (factory == wrappers[i].factory)
				results.add(wrappers[i].pid);
		}
		return results.toArray(new String[results.size()]);
	}

	public String[] getPids() {
		return getPids(false);
	}

	public String[] getFactoryPids() {
		return getPids(true);
	}

	public Bundle getBundle() {
		return _bundle;
	}

	@Override
	public EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale) {
		if (_bundle.getState() != Bundle.ACTIVE)
			return null; // return none if not active
		MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
		for (int i = 0; i < wrappers.length; i++) {
			if (id.equals(wrappers[i].pid))
				// found a matching pid now call the actual provider
				return wrappers[i].getObjectClassDefinition(id, locale);
		}
		return null;
	}

	public String[] getLocales() {
		if (_bundle.getState() != Bundle.ACTIVE)
			return new String[0]; // return none if not active
		MetaTypeProviderWrapper[] wrappers = getMetaTypeProviders();
		ArrayList<String> locales = new ArrayList<String>();
		// collect all the unique locales from all providers we found
		for (int i = 0; i < wrappers.length; i++) {
			String[] wrappedLocales = wrappers[i].getLocales();
			if (wrappedLocales == null)
				continue;
			for (int j = 0; j < wrappedLocales.length; j++)
				if (!locales.contains(wrappedLocales[j]))
					locales.add(wrappedLocales[j]);
		}
		return locales.toArray(new String[locales.size()]);
	}

	private MetaTypeProviderWrapper[] getMetaTypeProviders() {
		Map<ServiceReference<Object>, Object> services = _tracker.getTracked();
		if (services.isEmpty())
			return new MetaTypeProviderWrapper[0];
		Set<MetaTypeProviderWrapper> result = new HashSet<MetaTypeProviderWrapper>();
		for (Entry<ServiceReference<Object>, Object> entry : services.entrySet()) {
			ServiceReference<Object> serviceReference = entry.getKey();
			if (serviceReference.getBundle() == _bundle) {
				Object service = entry.getValue();
				// If the service is not a MetaTypeProvider, we're not interested in it.
				if (service instanceof MetaTypeProvider) {
					// Include the METATYPE_PID, if present, to return as part of getPids(). Also, include the 
					// METATYPE_FACTORY_PID, if present, to return as part of getFactoryPids().
					// The filter ensures at least one of these properties was set for a standalone MetaTypeProvider.
					addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_PID, serviceReference, (MetaTypeProvider) service, false, result);
					addMetaTypeProviderWrappers(MetaTypeProvider.METATYPE_FACTORY_PID, serviceReference, (MetaTypeProvider) service, true, result);
					// If the service is a ManagedService, include the SERVICE_PID to return as part of getPids().
					// The filter ensures the SERVICE_PID property was set.
					if (service instanceof ManagedService) {
						addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, false, result);
					}
					// If the service is a ManagedServiceFactory, include the SERVICE_PID to return as part of getFactoryPids().
					// The filter ensures the SERVICE_PID property was set.
					else if (service instanceof ManagedServiceFactory) {
						addMetaTypeProviderWrappers(Constants.SERVICE_PID, serviceReference, (MetaTypeProvider) service, true, result);
					}
				}
			}
		}
		return result.toArray(new MetaTypeProviderWrapper[result.size()]);
	}

	private void addMetaTypeProviderWrappers(String servicePropertyName, ServiceReference<Object> serviceReference, MetaTypeProvider service, boolean factory, Set<MetaTypeProviderWrapper> wrappers) {
		String[] pids = getStringProperty(servicePropertyName, serviceReference.getProperty(servicePropertyName));
		for (String pid : pids) {
			wrappers.add(new MetaTypeProviderWrapper(service, pid, factory));
		}
	}

	private String[] getStringProperty(String name, Object value) {
		// Don't log a warning if the value is null. The filter guarantees at least one of the necessary properties
		// is there. If others are not, this method will get called with value equal to null.
		if (value == null)
			return new String[0];
		if (value instanceof String) {
			return new String[] {(String) value};
		}
		if (value instanceof String[]) {
			return (String[]) value;
		}
		Exception e = null;
		if (value instanceof Collection) {
			@SuppressWarnings("unchecked")
			Collection<String> temp = (Collection<String>) value;
			try {
				return temp.toArray(new String[temp.size()]);
			} catch (ArrayStoreException ase) {
				e = ase;
			}
		}
		log.log(LogTracker.LOG_WARNING, NLS.bind(MetaTypeMsg.INVALID_PID_METATYPE_PROVIDER_IGNORED, new Object[] {_bundle.getSymbolicName(), _bundle.getBundleId(), name, value}), e);
		return new String[0];
	}

	// this is a simple class just used to temporarily store information about a provider
	public class MetaTypeProviderWrapper implements MetaTypeProvider {
		private final MetaTypeProvider provider;
		final String pid;
		final boolean factory;

		MetaTypeProviderWrapper(MetaTypeProvider provider, String pid, boolean factory) {
			this.provider = provider;
			this.pid = pid;
			this.factory = factory;
		}

		@Override
		public boolean equals(Object object) {
			if (object == this)
				return true;
			if (!(object instanceof MetaTypeProviderWrapper))
				return false;
			MetaTypeProviderWrapper that = (MetaTypeProviderWrapper) object;
			return this.provider.equals(that.provider) && this.pid.equals(that.pid) && this.factory == that.factory;
		}

		@Override
		public int hashCode() {
			int result = 17;
			result = 31 * result + provider.hashCode();
			result = 31 * result + pid.hashCode();
			result = 31 * result + (factory ? 1 : 0);
			return result;
		}

		public EquinoxObjectClassDefinition getObjectClassDefinition(String id, String locale) {
			final ObjectClassDefinition ocd = provider.getObjectClassDefinition(id, locale);
			if (ocd == null)
				return null;
			return new EquinoxObjectClassDefinition() {
				public String getName() {
					return ocd.getName();
				}

				public String getID() {
					return ocd.getID();
				}

				public String getDescription() {
					return ocd.getDescription();
				}

				public InputStream getIcon(int size) throws IOException {
					return ocd.getIcon(size);
				}

				@Override
				public Map<String, String> getExtensionAttributes(String schema) {
					return Collections.<String, String> emptyMap();
				}

				@Override
				public Set<String> getExtensionUris() {
					return Collections.<String> emptySet();
				}

				@Override
				public EquinoxAttributeDefinition[] getAttributeDefinitions(int filter) {
					AttributeDefinition[] ads = ocd.getAttributeDefinitions(filter);
					if (ads == null || ads.length == 0)
						return new EquinoxAttributeDefinition[0];
					Collection<EquinoxAttributeDefinition> result = new ArrayList<EquinoxAttributeDefinition>(ads.length);
					for (final AttributeDefinition ad : ads) {
						result.add(new EquinoxAttributeDefinition() {
							public String getName() {
								return ad.getName();
							}

							public String getID() {
								return ad.getID();
							}

							public String getDescription() {
								return ad.getDescription();
							}

							public int getCardinality() {
								return ad.getCardinality();
							}

							public int getType() {
								return ad.getType();
							}

							public String[] getOptionValues() {
								return ad.getOptionValues();
							}

							public String[] getOptionLabels() {
								return ad.getOptionLabels();
							}

							public String validate(String value) {
								return ad.validate(value);
							}

							public String[] getDefaultValue() {
								return ad.getDefaultValue();
							}

					    @Override
							public Map<String, String> getExtensionAttributes(String schema) {
								return Collections.<String, String> emptyMap();
							}

					    @Override
							public Set<String> getExtensionUris() {
								return Collections.<String> emptySet();
							}

					    @Override
							public String getMax() {
								return null;
							}

					    @Override
							public String getMin() {
								return null;
							}
						});
					}
					return result.toArray(new EquinoxAttributeDefinition[result.size()]);
				}
			};
		}

		public String[] getLocales() {
			return provider.getLocales();
		}
	}
}
