/*******************************************************************************
 * Copyright (c) 2018 Composent, Inc. 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:
 *   Composent, Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.ecf.osgi.services.remoteserviceadmin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.ecf.core.ContainerConnectException;
import org.eclipse.ecf.core.ContainerTypeDescription;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.IDCreateException;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.provider.ContainerInstantiatorUtils;
import org.eclipse.ecf.core.provider.ContainerIntentException;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.DebugOptions;
import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.IDUtil;
import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.LogUtility;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainer;
import org.eclipse.ecf.remoteservice.IRemoteServiceContainerAdapter;
import org.eclipse.ecf.remoteservice.RemoteServiceContainer;
import org.osgi.framework.ServiceReference;

/**
 * Abstract superclass for host container selectors...i.e. implementers of
 * {@link IHostContainerSelector}.
 * 
 */
public abstract class AbstractHostContainerSelector extends
		AbstractContainerSelector {

	private static final String REQUIRE_SERVER_PROP = "org.eclipse.ecf.osgi.service.remoteserviceadmin.hostcontainerselector.requireserver"; //$NON-NLS-1$
	private static final String EXCLUDED_DESCRIPTIONS_PROP = "org.eclipse.ecf.osgi.service.remoteserviceadmin.hostcontainerselector.excludeddescriptions"; //$NON-NLS-1$
	private boolean defaultRequireServer = new Boolean(System.getProperty(REQUIRE_SERVER_PROP,"true")); //$NON-NLS-1$
	private List<String> excludedDescriptions;
	
	protected String[] defaultConfigTypes;

	public AbstractHostContainerSelector(String[] defaultConfigTypes) {
		this.defaultConfigTypes = defaultConfigTypes;
		String propValue = System.getProperty(EXCLUDED_DESCRIPTIONS_PROP);
		String[] excludedVals = (propValue==null)?new String[0]:propValue.trim().split(","); //$NON-NLS-1$
		this.excludedDescriptions = Arrays.asList(excludedVals);
	}

	/**
	 * @param serviceReference service reference
	 * @param overridingProperties overriding properties
	 * @param serviceExportedInterfaces service exported interfaces to select for
	 * @param serviceExportedConfigs service exported configs to select for
	 * @param serviceIntents service exported intents to select for 
	 * @return Collection of existing host containers
	 * @since 2.0
	 */
	protected Collection selectExistingHostContainers(
			ServiceReference serviceReference,
			Map<String, Object> overridingProperties,
			String[] serviceExportedInterfaces,
			String[] serviceExportedConfigs, String[] serviceIntents) {
		List results = new ArrayList();
		// Get all existing containers
		IContainer[] containers = getContainers();
		// If nothing there, then return empty array
		if (containers == null || containers.length == 0)
			return results;

		for (int i = 0; i < containers.length; i++) {
			ID cID = containers[i].getID();
			trace("selectExistingHostContainers","Considering existing container="+cID); //$NON-NLS-1$ //$NON-NLS-2$
			// Check to make sure it's a rs container adapter. If it's not go
			// onto next one
			IRemoteServiceContainerAdapter adapter = hasRemoteServiceContainerAdapter(containers[i]);
			if (adapter == null) {
				trace("selectExistingHostContainers","Existing container="+cID+" does not implement IRemoteServiceContainerAdapter"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				continue;
			}
			// Get container type description and intents
			ContainerTypeDescription description = getContainerTypeDescription(containers[i]);
			// If it has no description go onto next
			if (description == null) {
				trace("selectExistingHostContainers","Existing container="+cID+" does not have container type description"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				continue;
			}
			// http://bugs.eclipse.org/331532
			if (!description.isServer()) {
				trace("selectExistingHostContainers","Existing container="+cID+" is not server"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				continue;
			}

			if (matchExistingHostContainer(serviceReference,
					overridingProperties, containers[i], adapter, description,
					serviceExportedConfigs, serviceIntents)) {
				trace("selectExistingHostContainers", "INCLUDING containerID=" //$NON-NLS-1$ //$NON-NLS-2$
						+ containers[i].getID()
						+ " configs=" //$NON-NLS-1$
						+ ((serviceExportedConfigs == null) ? "null" : Arrays //$NON-NLS-1$
								.asList(serviceExportedConfigs).toString())
						+ " intents=" //$NON-NLS-1$
						+ ((serviceIntents == null) ? "null" : Arrays.asList( //$NON-NLS-1$
								serviceIntents).toString()));
				results.add(new RemoteServiceContainer(containers[i], adapter));
			} else {
				trace("selectExistingHostContainers", "EXCLUDING containerID=" //$NON-NLS-1$ //$NON-NLS-2$
						+ containers[i].getID()
						+ " configs=" //$NON-NLS-1$
						+ ((serviceExportedConfigs == null) ? "null" : Arrays //$NON-NLS-1$
								.asList(serviceExportedConfigs).toString())
						+ " intents=" //$NON-NLS-1$
						+ ((serviceIntents == null) ? "null" : Arrays.asList( //$NON-NLS-1$
								serviceIntents).toString()));
			}
		}
		return results;
	}

	/**
	 * @param serviceReference serviceReference
	 * @param properties properties
	 * @param container container to match
	 * @return boolean true if match false otherwise
	 * @since 2.0
	 */
	protected boolean matchHostContainerToConnectTarget(
			ServiceReference serviceReference, Map<String, Object> properties,
			IContainer container) {
		String target = (String) properties
				.get(RemoteConstants.ENDPOINT_CONNECTTARGET_ID);
		if (target == null)
			return true;
		// If a targetID is specified, make sure it either matches what the
		// container
		// is already connected to, or that we connect an unconnected container
		ID connectedID = container.getConnectedID();
		// If the container is not already connected to anything
		// then we connect it to the given target
		if (connectedID == null) {
			// connect to the target and we have a match
			try {
				connectHostContainer(serviceReference, properties, container,
						target);
			} catch (Exception e) {
				logException("doConnectContainer containerID=" //$NON-NLS-1$
						+ container.getID() + " target=" + target, e); //$NON-NLS-1$
				return false;
			}
			return true;
		} else {
			ID targetID = createTargetID(container, target);
			// We check here if the currently connectedID equals the target.
			// If it does we have a match
			if (connectedID.equals(targetID))
				return true;
		}
		return false;
	}

	/**
	 * @param serviceReference service reference
	 * @param properties properties
	 * @param container container
	 * @param adapter remote service container adapter
	 * @param description container type description
	 * @param requiredConfigTypes required config types
	 * @param requiredServiceIntents required service intents
	 * @return boolean true if match, false otherwise
	 * @since 2.0
	 */
	protected boolean matchExistingHostContainer(
			ServiceReference serviceReference, Map<String, Object> properties,
			IContainer container, IRemoteServiceContainerAdapter adapter,
			ContainerTypeDescription description, String[] requiredConfigTypes,
			String[] requiredServiceIntents) {

		return matchHostSupportedConfigTypes(requiredConfigTypes, description)
				&& matchHostSupportedIntents(requiredServiceIntents,
						description, container)
				&& matchHostContainerID(serviceReference, properties, container)
				&& matchHostContainerToConnectTarget(serviceReference,
						properties, container);
	}

	/**
	 * @param serviceReference serviceReference
	 * @param properties properties
	 * @param container container
	 * @return boolean true if match, false otherwise
	 * @since 2.0
	 */
	protected boolean matchHostContainerID(ServiceReference serviceReference,
			Map<String, Object> properties, IContainer container) {

		ID containerID = container.getID();
		// No match if the container has no ID
		if (containerID == null)
			return false;

		// Then get containerid if specified directly by user in properties
		ID requiredContainerID = (ID) properties
				.get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_ID);
		// If the CONTAINER_I
		if (requiredContainerID != null) {
			return requiredContainerID.equals(containerID);
		}
		// Else get the container factory arguments, create an ID from the
		// arguments
		// and check if the ID matches that
		Namespace ns = containerID.getNamespace();
		Object cid = properties
				.get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_FACTORY_ARGS);
		// If no arguments are present, then any container ID should match
		if (cid == null)
			return true;
		ID cID = null;
		if (cid instanceof ID) {
			cID = (ID) cid;
		} else if (cid instanceof String) {
			cID = IDUtil.createID(ns, (String) cid);
		} else if (cid instanceof Object[]) {
			Object cido = ((Object[]) cid)[0];
			cID = IDUtil.createID(ns, new Object[] { cido });
		}
		if (cID == null)
			return true;
		return containerID.equals(cID);
	}

	/**
	 * @param requiredConfigTypes request config types
	 * @param containerTypeDescription container type description
	 * @return boolean true if match, false otherwise
	 */
	protected boolean matchHostSupportedConfigTypes(
			String[] requiredConfigTypes,
			ContainerTypeDescription containerTypeDescription) {
		// if no config type is set the spec requires to create a default
		// endpoint (see section 122.5.1)
		if (requiredConfigTypes == null)
			return true;
		trace("matchHostSupportedConfigTypes","description="+containerTypeDescription.getName()+" testing for requiredConfigTypes"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		// Get supported config types for this description
		String[] supportedConfigTypes = getSupportedConfigTypes(containerTypeDescription);
		// If it doesn't support anything, return false
		if (supportedConfigTypes == null || supportedConfigTypes.length == 0) {
			trace("matchHostSupportedConfigTypes","No supported configs found for description="+containerTypeDescription.getName()); //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		}
		// Turn supported config types for this description into list
		List supportedConfigTypesList = Arrays.asList(supportedConfigTypes);
		List requiredConfigTypesList = Arrays.asList(requiredConfigTypes);
		// We check all of the required config types and make sure
		// that one or more of them are present in the supportedConfigTypes
		boolean result = false;
		for (Iterator i = requiredConfigTypesList.iterator(); i.hasNext();)
			result |= supportedConfigTypesList.contains(i.next());
		if (!result)
			trace("matchHostSupportedConfigTypes","description="+containerTypeDescription.getName()+" does not support all required config types"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		return result;
	}

	/**
	 * @param serviceReference service reference
	 * @param properties overriding properties
	 * @param serviceExportedInterfaces service exported interfaces to select for
	 * @param requiredConfigs service exported configs to select for
	 * @param requiredIntents intents to select for 
	 * @return Collection of host containers
	 * @throws SelectContainerException if container cannot be created or configured
	 * @since 2.0
	 */
	protected Collection createAndConfigureHostContainers(
			ServiceReference serviceReference, Map<String, Object> properties,
			String[] serviceExportedInterfaces, String[] requiredConfigs,
			String[] serviceIntents) throws SelectContainerException {

		List results = new ArrayList();
		ContainerTypeDescription[] descriptions = getContainerTypeDescriptions();
		if (descriptions == null)
			return Collections.EMPTY_LIST;
			// Iterate through all descriptions and see if we have a match
			for (int i = 0; i < descriptions.length; i++) {
				trace("createAndConfigureHostContainers","Considering description="+descriptions[i]); //$NON-NLS-1$ //$NON-NLS-2$
				IRemoteServiceContainer matchingContainer = createMatchingContainer(
						descriptions[i], serviceReference, properties,
						serviceExportedInterfaces, requiredConfigs,
						serviceIntents);
				if (matchingContainer != null)
					results.add(matchingContainer);
			}
		return results;
	}

	protected ContainerTypeDescription[] getContainerTypeDescriptionsForDefaultConfigTypes(
			ContainerTypeDescription[] descriptions) {
		String[] defaultConfigTypes = getDefaultConfigTypes();
		if (defaultConfigTypes == null || defaultConfigTypes.length == 0)
			return null;
		List results = new ArrayList();
		for (int i = 0; i < descriptions.length; i++) {
			// For each description, get supported config types
			String[] supportedConfigTypes = descriptions[i]
					.getSupportedConfigs();
			if (supportedConfigTypes != null
					&& matchDefaultConfigTypes(defaultConfigTypes,
							supportedConfigTypes))
				results.add(descriptions[i]);
		}
		return (ContainerTypeDescription[]) results
				.toArray(new ContainerTypeDescription[] {});
	}

	protected boolean matchDefaultConfigTypes(String[] defaultConfigTypes,
			String[] supportedConfigTypes) {
		List supportedConfigTypesList = Arrays.asList(supportedConfigTypes);
		for (int i = 0; i < defaultConfigTypes.length; i++) {
			if (supportedConfigTypesList.contains(defaultConfigTypes[i]))
				return true;
		}
		return false;
	}

	protected String[] getDefaultConfigTypes() {
		return defaultConfigTypes;
	}

	/**
	 * @since 4.6
	 */
	protected boolean matchRequireServer(ContainerTypeDescription description) {
		boolean result = this.defaultRequireServer && description.isServer();
		LogUtility.trace("matchRequireServer", DebugOptions.CONTAINER_SELECTOR, this.getClass(), "description="+description.getName()+((result)?" matched require server":" DID NOT match require server")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		return result;
	}
	
	/**
	 * @since 4.6
	 */
	protected boolean matchNotExcluded(ContainerTypeDescription description) {
		boolean result = this.excludedDescriptions.contains(description.getName());
		LogUtility.trace("matchNotExcluded", DebugOptions.CONTAINER_SELECTOR, this.getClass(), "description="+description.getName()+((result)?" EXCLUDED via excludedDescriptions="+this.excludedDescriptions:" not excluded via excludedDescriptions="+this.excludedDescriptions)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		return !result;
	}
	/**
	 * @param containerTypeDescription containerTypeDescription
	 * @param serviceReference reference
	 * @param properties properties
	 * @param serviceExportedInterfaces exported interfaces
	 * @param requiredConfigs configs
	 * @param requiredIntents intents
	 * @return IRemoteServiceContainer matching container created
	 * @throws SelectContainerException container cannot be created or selected
	 * @since 2.0
	 */
	protected IRemoteServiceContainer createMatchingContainer(
			ContainerTypeDescription containerTypeDescription,
			ServiceReference serviceReference, Map<String, Object> properties,
			String[] serviceExportedInterfaces, String[] requiredConfigs,
			String[] serviceIntents) throws SelectContainerException {

		if (matchRequireServer(containerTypeDescription) && matchNotExcluded(containerTypeDescription)
				&& matchHostSupportedConfigTypes(requiredConfigs, containerTypeDescription)
				&& matchHostSupportedIntents(serviceIntents, containerTypeDescription)) {
			return createRSContainer(serviceReference, properties, containerTypeDescription, serviceIntents);
		}
		return null;
	}

	/**
	 * @param serviceReference serviceReference
	 * @param properties properties
	 * @param containerTypeDescription container type description
	 * @return IRemoteServiceContainer created remote service container
	 * @throws SelectContainerException if could not be created
	 * @since 2.0
	 */
	protected IRemoteServiceContainer createRSContainer(
			ServiceReference serviceReference, Map<String, Object> properties,
			ContainerTypeDescription containerTypeDescription)
			throws SelectContainerException {
		return createRSContainer(serviceReference, properties, containerTypeDescription, null);
	}

	/**
	 * @param serviceReference serviceReference
	 * @param properties properties
	 * @param containerTypeDescription container type description
	 * @return IRemoteServiceContainer created remote service container
	 * @throws SelectContainerException if could not be created
	 * @since 4.6
	 */
	protected IRemoteServiceContainer createRSContainer(
			ServiceReference serviceReference, Map<String, Object> properties,
			ContainerTypeDescription containerTypeDescription, String[] intents)
			throws SelectContainerException {
		trace("createRSContainer", //$NON-NLS-1$
				"Creating container instance for ref=" + serviceReference + ";properties=" + properties //$NON-NLS-1$ //$NON-NLS-2$
						+ ";description=" + containerTypeDescription.getName() + ";intents=" //$NON-NLS-1$ //$NON-NLS-2$
						+ ((intents == null) ? "" : Arrays.asList(intents).toString())); //$NON-NLS-1$
		IContainer container = createContainer(serviceReference, properties,
				containerTypeDescription, intents);
		if (container == null) 
			return null;
		IRemoteServiceContainerAdapter adapter = (IRemoteServiceContainerAdapter) container
				.getAdapter(IRemoteServiceContainerAdapter.class);
		if (adapter == null) {
			LogUtility.logError("createRSContainer", DebugOptions.CONTAINER_SELECTOR, this.getClass(), "Container="+container.getID()+" does not implement IRemoteServiceContainerAdapter"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return null;
		}
		return new RemoteServiceContainer(container, adapter);
	}


	/**
	 * @param serviceReference service reference
	 * @param properties properties
	 * @param container container
	 * @param target target
	 * @throws ContainerConnectException if container cannot be connected
	 * @throws IDCreateException thrown if ID cannot be created
	 * @since 2.0
	 */
	protected void connectHostContainer(ServiceReference serviceReference,
			Map<String, Object> properties, IContainer container, Object target)
			throws ContainerConnectException, IDCreateException {
		ID targetID = (target instanceof String) ? IDUtil.createID(
				container.getConnectNamespace(), (String) target) : IDUtil
				.createID(container.getConnectNamespace(),
						new Object[] { target });
		Object context = properties
				.get(RemoteConstants.SERVICE_EXPORTED_CONTAINER_CONNECT_CONTEXT);
		IConnectContext connectContext = null;
		if (context != null) {
			connectContext = createConnectContext(serviceReference, properties,
					container, context);
		}
		// connect the container
		container.connect(targetID, connectContext);
	}

	protected boolean matchHostSupportedIntents(
			String[] serviceRequiredIntents,
			ContainerTypeDescription containerTypeDescription) {
		return matchHostSupportedIntents(serviceRequiredIntents, containerTypeDescription, null);
	}

	/**
	 * @since 4.6
	 */
	protected boolean matchHostSupportedIntents(
			String[] serviceRequiredIntents,
			ContainerTypeDescription containerTypeDescription, IContainer container) {
		// If there are no required intents then we have a match
		if (serviceRequiredIntents == null)
			return true;

		trace("matchHostSupportedIntents","description="+containerTypeDescription.getName()+" testing for serviceRequiredIntents="+Arrays.asList(serviceRequiredIntents)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		
		String[] supportedIntents = getSupportedIntents(containerTypeDescription);

		if (supportedIntents == null) {
			trace("matchHostSupportedIntents","description="+containerTypeDescription.getName()+" does not have any supported intents"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return false;
		}
		// checks to see that containerTypeDescription supports requiredIntents
		boolean result = true;
		for (int i = 0; i < serviceRequiredIntents.length; i++) {
			boolean found = false;
			for(String supportedIntent: supportedIntents) 
				if (serviceRequiredIntents[i].equals(supportedIntent) || serviceRequiredIntents[i].startsWith(supportedIntent+"."))  {//$NON-NLS-1$
					found = true;
					break;
				}
			result &= found;
		}

		if (!result) {
			trace("matchHostSupportedIntents","description="+containerTypeDescription.getName()+" does not have all required intents"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return false;
		}
		
		// If container is non-null,
		// check to see that it's ID is private.  If it's not private, return null
		if (container != null) {
			try {
				if (ContainerInstantiatorUtils.containsPrivateIntent(serviceRequiredIntents))
					ContainerInstantiatorUtils.checkPrivate(container.getID());
			} catch (ContainerIntentException e) {
				trace("matchHostSupportedIntents","container="+container.getID()+" does not have osgi private intent"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				return false;
			}
		}
		
		if (!result) {
			trace("matchHostSupportedIntents","container="+container.getID()+" does not have all required intents"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		return result;
	}

}
