/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2007 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 * 
 * 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
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.compiler.adaptor;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.core.ClasspathAccessRule;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
import org.eclipse.osgi.service.resolver.StateHelper;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;

import base org.eclipse.pde.internal.core.PDEClasspathContainer;
import base org.eclipse.pde.internal.core.RequiredPluginsClasspathContainer;
import base org.eclipse.pde.internal.core.PDEClasspathContainer.Rule;
import base org.eclipse.pde.internal.core.bundle.BundlePluginModel;
import base org.eclipse.pde.internal.core.plugin.WorkspaceExtensionsModel;

/**
 * Adapt classes from the PDE core as to feed information about aspectBindings
 * into the compilation process (to be consumed by BaseImportChecker).
 * 
 * Final target as expected by the BaseImportChecker:
 *  + aspectBindingData (of type AdaptedBaseBundle) have been added to ClasspathAccessRules 
 *    and the problemID has been adjusted.
 * 
 * 
 * @author stephan
 * @since 1.1.5
 */
@SuppressWarnings("restriction")
public team class PDEAdaptor 
{
	static PDEAdaptor instance; 
	
	public PDEAdaptor() {
		instance= this;
	}

	/**
	 * <ul> 
	 * <li>Store aspectBinding info in Role objects.</li>
	 * <li>Add additional rules for forcedExports.</li>
	 * </ul> 
	 */
	protected class RequiredPluginsClasspathContainer
			extends PDEClasspathContainer
			playedBy RequiredPluginsClasspathContainer 
	{
		
		protected AspectBindingReader aspectBindingReader;
		
		void updateRule(String providingBundle, Rule rule) 
		 <- after Rule getRule(StateHelper helper, BundleDescription desc, ExportPackageDescription export)
			with { providingBundle <- export.getExporter().getSymbolicName(),
				   rule            <- result
			}
		/** Handles adaptation info for exported packages, Rule role created via regular lifting. */
		void updateRule(String providingBundle, Rule rule) {
			if (aspectBindingReader != null && aspectBindingReader.isAdaptedBase(providingBundle)) {
				// no merging because rule (base & role) are fresh instances
				rule.aspectBindingData= aspectBindingReader.getAdaptationInfo(providingBundle);
			}
		}
		
		@SuppressWarnings("decapsulation")
		Rule[] addForcedExports(BundleDescription desc) 
		 <- replace Rule[] getInclusions(Map<BundleDescription, ArrayList<Rule>> map, BundleDescription desc)
		    with { desc <- desc }
		/** Handles adaptation info for non-exported packages, Rule role explicitly created. */		
		callin Rule[] addForcedExports(BundleDescription desc) 
		{
			Rule[] regularRules= base.addForcedExports(desc);
			if (aspectBindingReader == null)
				return regularRules; // done: no aspect bindings
			HashSet<String> forcedExports= aspectBindingReader.getForcedExports(desc.getSymbolicName());
			if (forcedExports == null)
				return regularRules; // done: no forced exports
			
			AdaptedBaseBundle aspectBindingData= aspectBindingReader.getAdaptationInfo(desc.getSymbolicName());			
			// create additional rules:
			Rule[] additionalRules= new Rule[forcedExports.size()];
			Iterator<String> exportIter= forcedExports.iterator();
			for (int i = 0; i < additionalRules.length; i++) 
				additionalRules[i]= new Rule(aspectBindingData, exportIter.next());
			
			// merge arrays:
			int len1= regularRules.length, len2= additionalRules.length;
			Rule[] result= new Rule[len1+len2];
			System.arraycopy(additionalRules, 0, result, 0, len2);
			System.arraycopy(regularRules, 0, result, len2, len1);
			
			return result;
		}
		
		@SuppressWarnings("decapsulation")
		protected
		BundleModel getBundleModel() -> get IPluginModelBase fModel
			with { result <- (BundlePluginModel)fModel }

		// -- debug: --		
		String baseToString() => String toString();
		
		@SuppressWarnings("nls")
		@Override
		public String toString() {
			return "Role for "+baseToString()+" with aspectBindingReader\n  "
				  + ((this.aspectBindingReader != null) ? this.aspectBindingReader.toString() : "null");
		}
	}
	
	/**
	 * Synthetic rules representing adapted or forcedExports.
	 */
	@SuppressWarnings("decapsulation")
	protected class Rule playedBy Rule
	{
		void setPath(IPath path) -> set IPath path;

		// intermediate storage between AspectBindingReader and ClasspathAccessRule:
		protected AdaptedBaseBundle aspectBindingData; 
		protected boolean isForcedExport;
		
		/** Ctor for force-exported packages (merely adapted packages instantiate via lifting ctor). */
		protected Rule(AdaptedBaseBundle aspectBindingData, String packageName) 
		{
			base();
			String pattern= packageName.replace('.', '/')+"/*"; //$NON-NLS-1$
			setPath(new Path(pattern));
			this.aspectBindingData= aspectBindingData;
			this.isForcedExport= true;
		}
		// -- debug: --
		String baseToString() => String toString();
		
		@SuppressWarnings("nls")
		@Override
		public String toString() {
			String result= baseToString();
			if (this.isForcedExport)
				result+= " (forced export)";
			return result+" with aspect data\n  "
				  + ((this.aspectBindingData == null) ? "null" : this.aspectBindingData.toString());
		}		
	}
	
	/** After converting Rules to IAccessRules transfer adaptation info and adjust problemId. */
	protected class PDEClasspathContainer playedBy PDEClasspathContainer 
	{
		void getAccessRules(Rule[] rules, IAccessRule[] accessRules) 
		  <- after IAccessRule[] getAccessRules(Rule[] rules)
			 with { rules <- rules, accessRules <- result }
		static void getAccessRules(Rule[] rules, IAccessRule[] accessRules) {
			for (int i = 0; i < rules.length; i++) {
				Rule rule = rules[i];
				if (rule.aspectBindingData != null) {
					ClasspathAccessRule classpathAccessRule = (ClasspathAccessRule)accessRules[i];
					if (rule.isForcedExport) {
						// don't let this rule leak to other clients
						classpathAccessRule = new ClasspathAccessRule(classpathAccessRule.pattern, IProblem.BaseclassDecapsulationForcedExport);
						classpathAccessRule.aspectBindingData = new Object[] { rule.aspectBindingData };
						accessRules[i] = classpathAccessRule;
					} else { 
						addAspectBindingData(classpathAccessRule, rule.aspectBindingData);
					}
				}
			}
		}
	}
	/**
     * Add the given aspect binding data to the given access rule.
     * @return: has data been added (vs. merged or already present)? 
	 */
	public static boolean addAspectBindingData(ClasspathAccessRule accessRule, AdaptedBaseBundle aspectBindingData) {
		// nothing present yet?
		if (accessRule.aspectBindingData == null) {
			accessRule.aspectBindingData = new Object[] { aspectBindingData };
			if (accessRule.problemId == 0)
				accessRule.problemId= IProblem.AdaptedPluginAccess;
			return true;
		}
		// exact binding data already present?
		for (Object data : accessRule.aspectBindingData)
			if (data == aspectBindingData)
				return false;
		// different binding data for the same base bundle present?
		for (Object data : accessRule.aspectBindingData)
			if (((AdaptedBaseBundle)data).merge(aspectBindingData))
				return false;
		// different base bundles, must be the case of split packages
		for (Object data : accessRule.aspectBindingData)
			((AdaptedBaseBundle)data).hasPackageSplit = true;
		aspectBindingData.hasPackageSplit = true;
		int len = accessRule.aspectBindingData.length;
		Object[] newAspectBindingData = new Object[len+1];
		System.arraycopy(accessRule.aspectBindingData, 0, newAspectBindingData, 0, len);
		newAspectBindingData[len] = aspectBindingData;
		accessRule.aspectBindingData = newAspectBindingData;
		return true;
	}

	/** Helper role for updating aspect binding information. */
	protected class BundleModel playedBy BundlePluginModel {
		protected AspectBindingReader aspectBindingReader;
		
	}
	
	/** 
	 * This role listens to updates on its base.
	 * If the associated bundle model has a role with a registered
	 * aspect binding reader, trigger reloading when the model has changed. 
	 */
	protected class ModelListener playedBy WorkspaceExtensionsModel {
		void resetAspectReader() <- after void load(InputStream is, boolean reload);
		void resetAspectReader () {
			try {
				BundleModel bundle= getFBundleModel();
				if (bundle != null && bundle.aspectBindingReader != null)
					bundle.aspectBindingReader.reload();
			} catch (ClassCastException cce) {
				// CCE could be thrown by parameter mapping of getFBundleModel().
			}
		}
		/** This declaration is for documentation only: read the fBundleModel field.
		 * @return a BundleModel role
		 * @throws ClassCastException thrown when fBundleModel is not a BundlePluginModel.
		 */
		abstract BundleModel getFBundleModel() throws ClassCastException;
		@SuppressWarnings("decapsulation")
		BundleModel getFBundleModel() -> get IBundlePluginModelBase fBundleModel
			with { result <- (BundlePluginModel)fBundleModel }
	}

	/** Register an aspect binding reader for a given RequiredPluginsClasspathContainer. */
	void setAspectBindingReader(AspectBindingReader aspectBindingReader,
		RequiredPluginsClasspathContainer as RequiredPluginsClasspathContainer container) 
	{
		container.aspectBindingReader= aspectBindingReader;
		try {
			// link bundle model and reader for updating lateron:
			BundleModel bundle= container.getBundleModel();
			if (bundle != null)
				bundle.aspectBindingReader= aspectBindingReader;
		} catch (ClassCastException cce) {
			// can happen in param mapping of c-t-f, wrong model type, ignore.
		}
	}
}
