/***********************************************************************
 * Copyright (c) 2008 by SAP AG, Walldorf. 
 * 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:
 *     SAP AG - initial API and implementation
 ***********************************************************************/
package org.eclipse.jst.jee.model.internal;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.j2ee.model.IModelProviderEvent;
import org.eclipse.jst.javaee.core.EjbLocalRef;
import org.eclipse.jst.javaee.core.JavaEEObject;
import org.eclipse.jst.javaee.core.Listener;
import org.eclipse.jst.javaee.core.ResourceRef;
import org.eclipse.jst.javaee.core.SecurityRole;
import org.eclipse.jst.javaee.core.SecurityRoleRef;
import org.eclipse.jst.javaee.ejb.SecurityIdentityType;
import org.eclipse.jst.javaee.web.Filter;
import org.eclipse.jst.javaee.web.Servlet;
import org.eclipse.jst.javaee.web.WebApp;
import org.eclipse.jst.javaee.web.WebFactory;
import org.eclipse.jst.jee.model.internal.common.AbstractAnnotationModelProvider;
import org.eclipse.jst.jee.model.internal.common.ManyToOneRelation;
import org.eclipse.jst.jee.model.internal.common.Result;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;

/**
 * @author Kiril Mitov k.mitov@sap.com
 * 
 */
public class WebAnnotationReader extends AbstractAnnotationModelProvider<WebApp> {

	private ManyToOneRelation<JavaEEObject, ICompilationUnit> modelToUnit;

	private ManyToOneRelation<JavaEEObject, ICompilationUnit> modelToInterfaceUnit;

	private WebAnnotationFactory annotationFactory;

	private WebApp ddApp;

	public WebAnnotationReader(IFacetedProject facetedProject, WebApp ddApp) {
		super(facetedProject);
		if (ddApp == null)
			throw new IllegalArgumentException("The deployment descriptor model can not be null!"); //$NON-NLS-1$
		this.ddApp = ddApp;
	}

	@Override
	protected void preLoad() {
		modelObject = WebFactory.eINSTANCE.createWebApp();
		annotationFactory = WebAnnotationFactory.createFactory();
	}

	@Override
	protected void loadModel() throws CoreException {
		IJavaProject javaProject = JavaCore.create(facetedProject.getProject());
		final Collection<ICompilationUnit> javaUnits = new HashSet<ICompilationUnit>();
		for (final IPackageFragmentRoot root : javaProject.getAllPackageFragmentRoots()) {
			visitJavaFiles(javaUnits, root);
		}
		annotationFactory = WebAnnotationFactory.createFactory();

		modelToInterfaceUnit = new ManyToOneRelation<JavaEEObject, ICompilationUnit>();
		modelToUnit = new ManyToOneRelation<JavaEEObject, ICompilationUnit>();
		for (ICompilationUnit unit : javaUnits) {
			Result result = analyzeCompilationUnit(unit);
			if (result == null)
				continue;
			processResult(unit, result);
		}
	}

	/**
	 * Analyze this unit for a web artifact. If the file is not a valid java
	 * compilation unit or it does not contain a class the method returns
	 * <code>null</code>
	 * 
	 * Only the primary type of the compilation unit is processed.
	 * 
	 * @param unit
	 *            the unit to be processed.
	 * @return result from processing the file
	 * @throws JavaModelException
	 */
	private Result analyzeCompilationUnit(ICompilationUnit unit) throws JavaModelException {
		IType rootType = unit.findPrimaryType();
		/*
		 * If the compilation unit is not valid and can not be compiled the
		 * rootType may be null. This can happen if a class is define as follows
		 * <code> @Stateless public SomeClass implements SomeInterface{}</code>.
		 * Here the "class" word is missed and the type is not valid.
		 */
		if (rootType == null || !rootType.isClass())
			return null;
		for (Iterator iter = ddApp.getServlets().iterator(); iter.hasNext();) {
			Servlet servlet = (Servlet) iter.next();
			if (rootType.getFullyQualifiedName().equals(servlet.getServletClass()))
				return annotationFactory.createServlet(rootType, servlet.getServletName());
		}
		for (Iterator iter = ddApp.getListeners().iterator(); iter.hasNext();) {
			Listener listener = (Listener) iter.next();
			if (rootType.getFullyQualifiedName().equals(listener.getListenerClass()))
				return annotationFactory.createListener(rootType);
		}
		for (Iterator iter = ddApp.getFilters().iterator(); iter.hasNext();) {
			Filter filter = (Filter) iter.next();
			if (rootType.getFullyQualifiedName().equals(filter.getFilterClass())) {
				return annotationFactory.createFilter(rootType, filter.getFilterName());
			}
		}
		return null;
	}

	/**
	 * Process the result from parsing the unit. Depending on the result this
	 * might include adding a session bean, message driven bean, securityRole
	 * etc.
	 * 
	 * @param unit
	 * @param result
	 * @throws JavaModelException
	 */
	private void processResult(ICompilationUnit unit, Result result) throws JavaModelException {
		JavaEEObject mainObject = result.getMainObject();
		if (Servlet.class.isInstance(mainObject))
			servletFound(unit, (Servlet) result.getMainObject(), result.getDependedTypes());
		for (JavaEEObject additional : result.getAdditional()) {
			if (EjbLocalRef.class.isInstance(additional)) {
				ejbLocalRefFound(unit, (EjbLocalRef) additional, result.getDependedTypes());
			} else if (ResourceRef.class.isInstance(additional)) {
				resourceRefFound(unit, (ResourceRef) additional, result.getDependedTypes());
			} else if (SecurityRole.class.isInstance(additional)) {
				securityRoleFound(result.getMainObject(), (SecurityRole) additional);
			} else if (SecurityIdentityType.class.isInstance(additional)) {
				securityIdentityTypeFound(unit, (SecurityIdentityType) additional);
			}
		}
	}

	private void servletFound(ICompilationUnit unit, Servlet servlet, Collection<IType> dependedTypes)
			throws JavaModelException {
		modelObject.getServlets().add(servlet);
		connectObjectWithFile(unit, servlet, dependedTypes);
	}

	private void securityIdentityTypeFound(ICompilationUnit file, SecurityIdentityType additional) {
	}

	private void resourceRefFound(ICompilationUnit unit, ResourceRef resourceRef, Collection<IType> dependedTypes)
			throws JavaModelException {
		modelObject.getResourceRefs().add(resourceRef);
		connectObjectWithFile(unit, resourceRef, dependedTypes);
	}

	private void ejbLocalRefFound(ICompilationUnit unit, EjbLocalRef localRef, Collection<IType> dependedTypes)
			throws JavaModelException {
		modelObject.getEjbLocalRefs().add(localRef);
		connectObjectWithFile(unit, localRef, dependedTypes);
	}

	private void connectObjectWithFile(ICompilationUnit unit, JavaEEObject localRef, Collection<IType> dependedTypes)
			throws JavaModelException {
		modelToUnit.connect(localRef, unit);
		for (IType type : dependedTypes) {
			if (type.isBinary() || type.isInterface() == false)
				continue;
			modelToInterfaceUnit.connect(localRef, type.getCompilationUnit());
		}
	}

	@Override
	protected void processAddedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit)
			throws CoreException {
		Result result = analyzeCompilationUnit(unit);
		if (result == null || result.isEmpty())
			return;
		processResult(unit, result);
		modelEvent.addResource(unit);
	}

	@Override
	protected void processChangedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit)
			throws CoreException {
		if (modelToUnit.containsTarget(unit))
			processChangedModelUnit(modelEvent, unit);
		else
			processAddedCompilationUnit(modelEvent, unit);
	}

	private void processChangedModelUnit(IModelProviderEvent modelEvent, ICompilationUnit unit) throws CoreException {
		processRemovedCompilationUnit(modelEvent, unit);
		processAddedCompilationUnit(modelEvent, unit);
	}

	@Override
	protected void processRemovedCompilationUnit(IModelProviderEvent modelEvent, ICompilationUnit unit)
			throws CoreException {
		if (modelToUnit.containsTarget(unit))
			processRemovedModelResource(modelEvent, unit);
		else if (modelToInterfaceUnit.containsTarget(unit))
			processRemoveInterface(modelEvent, unit);
	}

	private void processRemoveInterface(IModelProviderEvent event, ICompilationUnit unit) {
	}

	@Override
	protected void processRemovedPackage(IModelProviderEvent modelEvent, IJavaElementDelta delta) throws CoreException {
		for (ICompilationUnit unit : modelToUnit.getTargets()) {
			if (unit.getParent().getElementName().equals(delta.getElement().getElementName())) {
				processRemovedCompilationUnit(modelEvent, unit);
			}
		}
	}

	private void processRemovedModelResource(IModelProviderEvent event, ICompilationUnit file) {
		Collection<JavaEEObject> modelObjects = modelToUnit.getSources(file);
		for (JavaEEObject o : modelObjects) {
			if (Servlet.class.isInstance(o))
				disconnectFromRoles(o);
			EcoreUtil.remove((EObject) o);
		}
		modelToUnit.disconnect(file);
		event.setEventCode(event.getEventCode() | IModelProviderEvent.REMOVED_RESOURCE);
		event.addResource(file);
	}

	public void modify(Runnable runnable, IPath modelPath) {
	}

	public IStatus validateEdit(IPath modelPath, Object context) {
		return null;
	}

	@Override
	protected Collection<SecurityRoleRef> getSecurityRoleRefs(JavaEEObject target) {
		if (Servlet.class.isInstance(target))
			return ((Servlet) target).getSecurityRoleRefs();
		return null;
	}

	@Override
	protected Collection<SecurityRole> getSecurityRoles() {
		return modelObject.getSecurityRoles();
	}

}
