/*****************************************************************************
 * Copyright (c) 2013, 2017 CEA LIST and others.
 *
 * All rights reserved. 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:
 *   CEA LIST - Initial API and implementation
 *   Christian W. Damus (CEA) - bug 429242
 *
 *****************************************************************************/
package org.eclipse.papyrus.cdo.internal.core.importer;

import java.util.Collection;
import java.util.Set;

import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.cdo.internal.core.Activator;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.resource.ModelsReader;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
import org.eclipse.papyrus.infra.core.sashwindows.di.util.DiUtils;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

/**
 * This is the DependencyAdapter type. Enjoy.
 */
public class DependencyAdapter extends AdapterImpl {

	private final ModelsReader modelsMetadata = new ModelsReader();

	private final Set<Resource> dependencies = Sets.newLinkedHashSet();

	private final Set<Resource> dependents = Sets.newLinkedHashSet();

	private DependencyAdapter() {
		super();
	}

	public static DependencyAdapter getInstance(Resource resource) {
		DependencyAdapter result = getExistingInstance(resource);

		if (result == null) {
			result = new DependencyAdapter();
			resource.eAdapters().add(Math.min(1, resource.eAdapters().size()), result);

			result.analyze(resource);
		}

		return result;
	}

	static DependencyAdapter getExistingInstance(Resource resource) {
		DependencyAdapter result = null;

		for (Object next : resource.eAdapters()) {
			if (next instanceof DependencyAdapter) {
				result = (DependencyAdapter) next;
				break;
			}
		}

		return result;
	}

	public Set<Resource> getDependencies() {
		return dependencies;
	}

	public static Set<Resource> getDependencies(Resource resource) {
		return getInstance(resource).getDependencies();
	}

	public Set<Resource> getDependents() {
		return dependents;
	}

	public static Set<Resource> getDependents(Resource resource) {
		return getInstance(resource).getDependents();
	}

	private void analyze(Resource resource) {
		if (resource.getContents().isEmpty() && isDIResource(resource)) {
			// similarly-named resources that are recognized by Papyrus are implicitly components
			for (Resource next : getImplicitComponents(resource)) {
				if (isUserModelResource(next.getURI())) {
					addDependency(next);
				}
			}
		} else {
			for (TreeIterator<EObject> iter = EcoreUtil.getAllProperContents(resource, false); iter.hasNext();) {
				EObject next = iter.next();

				// ignore annotations, such as are used for hyperlinks
				if (next instanceof EAnnotation) {
					iter.prune();
				} else {
					for (EObject xref : next.eCrossReferences()) {
						Resource xrefRes = xref.eResource();
						if ((xrefRes != null) && (isUserModelResource(xrefRes.getURI()))) {
							addDependency(xrefRes);
						}
					}
				}
			}
		}
	}

	private Resource getResource() {
		return (Resource) getTarget();
	}

	void addDependency(Resource resource) {
		Resource self = getResource();

		if ((resource != self) && dependencies.add(resource)) {
			getInstance(resource).addDependent(self);
		}
	}

	private void addDependent(Resource resource) {
		if (resource != getResource()) {
			dependents.add(resource);
		}
	}

	boolean isUserModelResource(URI uri) {
		ModelSet modelSet = getModelSet();
		boolean result = (modelSet != null) ? modelSet.isUserModelResource(uri) :
				// config.hasResource(uri) &&
				uri.isPlatformResource() || uri.isFile() || CDOUtils.isCDOURI(uri);

		return result && !uri.isArchive();
	}

	private ModelSet getModelSet() {
		return CDOUtils.adapt(getResource().getResourceSet(), ModelSet.class);
	}

	private Iterable<Resource> getImplicitComponents(Resource diResource) {
		// usually only two components: diagrams and semantics
		Collection<Resource> result = Lists.newArrayListWithExpectedSize(2);

		ResourceSet rset = diResource.getResourceSet();
		URIConverter converter = rset.getURIConverter();

		for (URI next : modelsMetadata.getKnownModelURIs(diResource.getURI())) {
			if (!next.equals(diResource.getURI()) && converter.exists(next, null)) {
				try {
					result.add(rset.getResource(next, true));
				} catch (Exception e) {
					Activator.log.error("Uncaught exception in loading component of Papyrus model.", e); //$NON-NLS-1$
				}
			}
		}

		return result;
	}

	public static boolean isDIResource(Resource resource) {
		boolean result = false;

		if (resource.getContents().isEmpty()) {
			// DI resources are typically empty; just markers
			result = DiModel.DI_FILE_EXTENSION.equals(resource.getURI().fileExtension());
		} else {
			// Look for legacy DI content (the Sash Model that now is in a *.sash resource in the workspace metadata area)
			result = DiUtils.lookupSashWindowsMngr(resource) != null;
		}

		return result;
	}

	public static Resource getDIResource(Resource resource) {
		Resource result = null;

		if (isDIResource(resource)) {
			result = resource;
		} else {
			// find the the DI resource
			ResourceSet rset = resource.getResourceSet();
			URI uri = resource.getURI().trimFileExtension().appendFileExtension(DiModel.DI_FILE_EXTENSION);
			if (rset.getURIConverter().exists(uri, null)) {
				Resource di = rset.getResource(uri, true);

				if ((di != null) && isDIResource(di)) {
					result = di;
				}
			}
		}

		return result;
	}
}
