/*******************************************************************************
 * Copyright (c) 2010, 2016 Willink Transformations 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:
 *     E.D.Willink - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.xtext.base.scoping;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.PrimitiveType;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.internal.scoping.Attribution;
import org.eclipse.ocl.pivot.internal.scoping.EnvironmentView;
import org.eclipse.ocl.pivot.internal.scoping.NullAttribution;
import org.eclipse.ocl.pivot.internal.scoping.ScopeView;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.internal.utilities.IllegalLibraryException;
import org.eclipse.ocl.pivot.internal.utilities.PivotObjectImpl;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.utilities.Pivotable;
import org.eclipse.ocl.xtext.base.as2cs.AliasAnalysis;
import org.eclipse.ocl.xtext.basecs.BaseCSPackage;
import org.eclipse.ocl.xtext.basecs.ContextLessElementCS;
import org.eclipse.ocl.xtext.basecs.ElementCS;
import org.eclipse.ocl.xtext.basecs.ModelElementCS;
import org.eclipse.ocl.xtext.basecs.TemplateBindingCS;
import org.eclipse.ocl.xtext.basecs.TemplateParameterSubstitutionCS;
import org.eclipse.ocl.xtext.basecs.TypeRefCS;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractScope;

/**
 * ScopeViews support access to some or all of the elements in a scope.
 * Accesses are filtered on the fly since a cache of results does not remain valid
 * for long enough to merit it, with incremental reparsing regularly trashing
 * the CST.
 */
public class BaseScopeView extends AbstractScope implements IScopeView
{
	private static final Logger logger = Logger.getLogger(BaseScopeView.class);

	/**
     * The <code>NULLSCOPEVIEW</code> to be returned by the most outer scope
     */
    public static final @NonNull IScopeView NULLSCOPEVIEW = new IScopeView()
    {
 		@Override
		public Iterable<IEObjectDescription> getAllElements() {
	   		return Collections.emptyList();
		}

		@Override
		public @NonNull Attribution getAttribution() {
			return NullAttribution.INSTANCE;
		}

		@Override
		public ElementCS getChild() {
			return null;
		}

		@Override
		public EStructuralFeature getContainmentFeature() {
			return null;
		}

		@Override
		public Iterable<IEObjectDescription> getElements(EObject object) {
	   		return Collections.emptyList();
		}

		@Override
		public Iterable<IEObjectDescription> getElements(QualifiedName name) {
	   		return Collections.emptyList();
		}

		@Override
		public @NonNull IScopeView getParent() {
			return NULLSCOPEVIEW;
		}

		@Override
		public @NonNull IScopeView getRoot() {
			return NULLSCOPEVIEW;
		}

		@Override
		public IEObjectDescription getSingleElement(QualifiedName name) {
			return null;
		}

		@Override
		public IEObjectDescription getSingleElement(EObject object) {
			return null;
		}

		@Override
		public ElementCS getTarget() {
			return null;
		}

		@Override
		public boolean isQualified() {
			return false;
		}
    };

	public static @NonNull BaseScopeView getScopeView(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull ElementCS target, @NonNull EReference targetReference) {
		return new BaseScopeView(environmentFactory, target, null, targetReference, false);
	}

	private static @NonNull IScopeView getParent(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull ElementCS target, @NonNull EReference targetReference, boolean isQualified) {
		ElementCS csParent = target.getParent();
		if (csParent == null) {
			return NULLSCOPEVIEW;
		}
		return new BaseScopeView(environmentFactory, csParent, target, targetReference, isQualified);
	}
	
	protected final @NonNull EnvironmentFactoryInternal environmentFactory;
	protected final @NonNull ElementCS target;							// CS node in which a lookup is to be performed
	protected final @Nullable ElementCS child;							// CS node from which a lookup is to be performed
	protected final @NonNull EReference targetReference;				// The AST reference to the location at which the lookup is to be stored
	protected final boolean isQualified;
	private Attribution attribution = null;								// Lazily computed Attributes helper for the target CS node

	protected BaseScopeView(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull ElementCS target, @Nullable ElementCS child, @NonNull EReference targetReference, boolean isQualified) {
		super(getParent(environmentFactory, target, targetReference, isQualified), false);
		this.environmentFactory = environmentFactory;
		this.target = target;
		this.child = child;
		this.targetReference = targetReference;
		this.isQualified = isQualified;
	}

	@Override
	public @NonNull Attribution getAttribution() {
		Attribution attribution2 = attribution;
		if (attribution2 == null) {
			attribution = attribution2 = PivotUtilInternal.getAttribution(target);
		}
		return attribution2;
	}

	@Override
	public Iterable<IEObjectDescription> getAllElements() {
		EnvironmentView environmentView = new EnvironmentView(environmentFactory, targetReference, null);
		try {
//			computeLookupWithParents(environmentView);
			Attribution attribution = getAttribution();
			ScopeView aScope = attribution.computeLookup(target, environmentView, this);
			if (aScope != null) {
				environmentView.computeLookups(aScope);
			}
		} catch (IllegalLibraryException e) {			
		}
		return getDescriptions(environmentView);
	}

	@Override
	protected final Iterable<IEObjectDescription> getAllLocalElements() {
		EnvironmentView environmentView = new EnvironmentView(environmentFactory, targetReference, null);
		Attribution attribution = getAttribution();
		attribution.computeLookup(target, environmentView, this);
		return getDescriptions(environmentView);
	}

	@Override
	public @Nullable ElementCS getChild() {
		return child;
	}

	@Override
	public EStructuralFeature getContainmentFeature() {
//		assert ((child == null) && (containmentFeature == null)) || ((child != null) && (child.eContainmentFeature() ==  containmentFeature));
		return child != null ? child.eContainmentFeature() : targetReference;
	}

	private @NonNull Element getContextRoot(@NonNull Element context) {
		while (!(context instanceof Namespace) && !(context instanceof Type)) {
			EObject container = context.eContainer();
			if (container instanceof Element) {
				context = (Element) container;
			}
			else {
				break;
			}
		}
		return context;
	}

	private @Nullable IEObjectDescription getDescription(EnvironmentView environmentView) {
		int contentsSize = environmentView.getSize();
		if (contentsSize == 0) {
			return null;
		}
		if (contentsSize != 1) {
			logger.warn("Unhandled ambiguous content for '" + environmentView.getName() + "'");
		}
		for (Map.Entry<String, Object> entry : environmentView.getEntries()) {
			Object value = entry.getValue();
			if (value instanceof List<?>) {
				List<?> values = (List<?>) value;
				value = values.get(values.size() - 1);
			}
			if (value instanceof EObject) {
				return EObjectDescription.create(entry.getKey(), (EObject) value);
			}
		}
		return null;
	}

	private @NonNull List<IEObjectDescription> getDescriptions(EnvironmentView environmentView) {
		List<IEObjectDescription> contents = new ArrayList<IEObjectDescription>();
		for (Map.Entry<String, Object> entry : environmentView.getEntries()) {
			Object values = entry.getValue();
			if (values instanceof EObject) {
				contents.add(EObjectDescription.create(entry.getKey(),
					(EObject) values));
			} else if (values instanceof List<?>) {
				for (Object value : (List<?>) values) {
					contents.add(EObjectDescription.create(entry.getKey(),
						(EObject) value));
				}
			}
		}
		return contents;
	}

	@Override
	public /*@NonNull*/ Iterable<IEObjectDescription> getElements(QualifiedName name) {
		if (name == null)
			throw new NullPointerException("name"); //$NON-NLS-1$
		EnvironmentView environmentView = new EnvironmentView(environmentFactory, targetReference, name.toString());
		int size = environmentView.computeLookups(this);
		if (size <= 0) {
			return Collections.emptyList();
		}
		else if (size == 1) {
			return Collections.singletonList(getDescription(environmentView));
		}
		else {
			List<IEObjectDescription> contents = getDescriptions(environmentView);
			return contents;
		}
	}

	@Override
	public /*@NonNull*/ Iterable<IEObjectDescription> getElements(EObject object) {
		String descriptiveName = null;
		if (targetReference == BaseCSPackage.Literals.IMPORT_CS__REFERRED_NAMESPACE) {
			descriptiveName = getNonASURI(object);
		}
		else if (targetReference == BaseCSPackage.Literals.MODEL_ELEMENT_REF_CS__REFERRED_ELEMENT) {
			descriptiveName = getNonASURI(object);
		}
		else if (targetReference == BaseCSPackage.Literals.REFERENCE_CS__REFERRED_OPPOSITE) {
			descriptiveName = ((NamedElement)object).getName();
		}
		else if (targetReference == BaseCSPackage.Literals.REFERENCE_CS__REFERRED_KEYS) {
			descriptiveName = ((NamedElement)object).getName();
		}
		else if ((targetReference == BaseCSPackage.Literals.TYPED_TYPE_REF_CS__REFERRED_TYPE) && (object instanceof Type)) {
			if (object instanceof PrimitiveType) {		// FIXME Redundant if namespaces correct
				descriptiveName = ((PrimitiveType)object).getName();
			}
			else {
				EObject csRef = getTarget();
				while ((csRef.eContainer() instanceof TypeRefCS)
						|| (csRef.eContainer() instanceof TemplateParameterSubstitutionCS)
						|| (csRef.eContainer() instanceof TemplateBindingCS)) {
					csRef = csRef.eContainer();
				}
				ModelElementCS csContext = (ModelElementCS) csRef.eContainer();
				Resource eResource = EcoreUtil.getRootContainer(csContext).eResource();
				if (eResource == null) {
					return Collections.emptyList();
				}
				AliasAnalysis aliasAnalysis = AliasAnalysis.getAdapter(eResource, environmentFactory);
				Element context = csContext.getPivot();
				if (context == null) {
					return Collections.emptyList();
				}
				context = getContextRoot(context);
				QualifiedPath contextPath = new QualifiedPath(aliasAnalysis.getPath(context));
				QualifiedPath objectPath = new QualifiedPath(aliasAnalysis.getPath((Element) object));
				QualifiedPath qualifiedRelativeName = objectPath.deresolve(contextPath);
				IEObjectDescription objectDescription = EObjectDescription.create(qualifiedRelativeName, object);
				return Collections.singletonList(objectDescription);
			}
		}
		else if (object instanceof NamedElement) {
			EObject csRef = getTarget();
			while ((csRef.eContainer() instanceof ContextLessElementCS)
					|| (csRef.eContainer() instanceof TypeRefCS)
					|| (csRef.eContainer() instanceof TemplateParameterSubstitutionCS)
					|| (csRef.eContainer() instanceof TemplateBindingCS)) {
				csRef = csRef.eContainer();
			}
			Pivotable csContext = (Pivotable) csRef.eContainer();
			Resource eResource = csContext.eResource();
			if (eResource == null) {
				return Collections.emptyList();
			}
			AliasAnalysis aliasAnalysis = AliasAnalysis.getAdapter(eResource, environmentFactory);
			Element context = csContext.getPivot();
			if (context == null) {
				return Collections.emptyList();
			}
			context = getContextRoot(context);
			QualifiedPath contextPath = new QualifiedPath(aliasAnalysis.getPath(context));
			QualifiedPath objectPath = new QualifiedPath(aliasAnalysis.getPath((Element) object));
			QualifiedPath qualifiedRelativeName = objectPath.deresolve(contextPath);
			IEObjectDescription objectDescription = EObjectDescription.create(qualifiedRelativeName, object);
			return Collections.singletonList(objectDescription);
		}
		if (descriptiveName != null) {
			IEObjectDescription objectDescription = EObjectDescription.create(descriptiveName, object);
			return Collections.singletonList(objectDescription);
		}
		return super.getElements(object);		// FIXME Implement
	}

//	public MetamodelManager getMetamodelManager() {
//		return metamodelManager;
//	}
	
	private @Nullable String getNonASURI(@Nullable EObject object) {
		URI uri = null;
		if (object == null) {
			return null;
		}
		if (object instanceof PivotObjectImpl) {
			EObject target = ((PivotObjectImpl)object).getESObject();
			if (target != null) {
				uri = EcoreUtil.getURI(target);
			}
		}
		if (uri == null) {
			uri = EcoreUtil.getURI(object);
		}
		if (PivotUtilInternal.isASURI(uri)) {
			uri = PivotUtilInternal.getNonASURI(uri);
		}
		return uri.toString();
	}

	@Override
	public @NonNull IScopeView getParent() {
		IScope parent = super.getParent();
		assert parent instanceof IScopeView;
		return (IScopeView) parent;
	}

	@Override
	public @NonNull IScopeView getRoot() {
		IScopeView parent = getParent();
		if (parent == NULLSCOPEVIEW) {
			return this;
		}
		else {
			return parent.getRoot();
		}
	}

	@Override
	public IEObjectDescription getSingleElement(EObject object) {
		if (object instanceof NamedElement) {
			return EObjectDescription.create(((NamedElement)object).getName(), object);
		}
		else {
			return super.getSingleElement(object);		// FIXME Implement
		}
	}

	@Override
	public @Nullable IEObjectDescription getSingleElement(QualifiedName name) {
		if (name == null)
			throw new NullPointerException("name"); //$NON-NLS-1$
		EnvironmentView environmentView = new EnvironmentView(environmentFactory, targetReference, name.toString());
		int size = environmentView.computeLookups(this);
		if (size <= 0) {
			return null;
		}
		else if (size == 1) {
			return getDescription(environmentView);
		}
		else {
			return null;			// FIXME Return an 'ambiguous' description
//			return environmentView.getDescriptions().get(0);
		}
	}

	@Override
	public final @NonNull ElementCS getTarget() {
		return target;
	}
	
	@Override
	public final boolean isQualified() {
		return isQualified;
	}

	@Override
	public String toString() {
		EObject target = getTarget();
		StringBuilder s = new StringBuilder();
		s.append("["); //$NON-NLS-1$
		s.append(target.eClass().getName());
		EStructuralFeature containmentFeature2 = getContainmentFeature();
		if (containmentFeature2 != null) {
			s.append("::"); //$NON-NLS-1$
			s.append(containmentFeature2.getName());
		}
		s.append("] "); //$NON-NLS-1$
		s.append(String.valueOf(target));
		return s.toString();
	}
}
