/***********************************************************************
 * 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.ArrayList;
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.IAnnotation;
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.j2ee.web.project.facet.WebFacetUtils;
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.FilterMapping;
import org.eclipse.jst.javaee.web.Servlet;
import org.eclipse.jst.javaee.web.ServletMapping;
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 static final String WEB_SERVLET = "WebServlet"; //$NON-NLS-1$
	private static final String WEB_SERVLET_FQ = "javax.servlet.annotation.WebServlet"; //$NON-NLS-1$
	
	private static final String WEB_LISTENER = "WebListener"; //$NON-NLS-1$
	private static final String WEB_LISTENER_FQ = "javax.servlet.annotation.WebListener"; //$NON-NLS-1$

	private static final String WEB_FILTER = "WebFilter"; //$NON-NLS-1$
	private static final String WEB_FILTER_FQ = "javax.servlet.annotation.WebFilter"; //$NON-NLS-1$

	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());
			}
		}
		if(Float.parseFloat(facetedProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET).getVersionString()) > 2.5){
			return createJavaeeObject(rootType);	
		}
		return null;
	}
	
	public Result createJavaeeObject(IType type) throws JavaModelException {
		Result result = null;
		for (IAnnotation annotation : type.getAnnotations()) {
			String annotationName = annotation.getElementName();
			if (WEB_SERVLET.equals(annotationName) || WEB_SERVLET_FQ.equals(annotationName)) {
				result = annotationFactory.createServlet(type, null);
				break;
			} else if (WEB_FILTER.equals(annotationName) || WEB_FILTER_FQ.equals(annotationName)) {
				result = annotationFactory.createFilter(type, null);
				break;
			} else if (WEB_LISTENER.equals(annotationName) || WEB_LISTENER_FQ.equals(annotationName)) {
				result = annotationFactory.createListener(type);
				break;
			} 
		}
		return result;
	}

	/**
	 * 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());
		if (Listener.class.isInstance(mainObject))
			listenerFound(unit, (Listener) result.getMainObject(), result.getDependedTypes());
		if (Filter.class.isInstance(mainObject))
			filterFound(unit, (Filter) 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);
			} else if (ServletMapping.class.isInstance(additional)) {
				servletMappingFound(unit, (ServletMapping)additional, result.getDependedTypes());
			} else if (FilterMapping.class.isInstance(additional)) {
				filterMappingFound(unit, (FilterMapping)additional, result.getDependedTypes());
			}
		}
	}

	private void filterMappingFound(ICompilationUnit unit,
			FilterMapping additional, Collection<IType> dependedTypes) throws JavaModelException {
		modelObject.getFilterMappings().add(additional);
		connectObjectWithFile(unit, additional, dependedTypes);
	}

	private void servletMappingFound(ICompilationUnit unit,
			ServletMapping additional, Collection<IType> dependedTypes) throws JavaModelException {
		modelObject.getServletMappings().add(additional);
		connectObjectWithFile(unit, additional, dependedTypes);
	}

	private void servletFound(ICompilationUnit unit, Servlet servlet, Collection<IType> dependedTypes) throws JavaModelException {
		modelObject.getServlets().add(servlet);
		connectObjectWithFile(unit, servlet, dependedTypes);
	}
	
	private void listenerFound(ICompilationUnit unit, Listener listener, Collection<IType> dependedTypes) throws JavaModelException {
		modelObject.getListeners().add(listener);
		connectObjectWithFile(unit, listener, dependedTypes);
	}
	
	private void filterFound(ICompilationUnit unit, Filter filter, Collection<IType> dependedTypes) throws JavaModelException {
		modelObject.getFilters().add(filter);
		connectObjectWithFile(unit, filter, 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 {
		Collection<ICompilationUnit> clonedCollection = cloneCollection(modelToUnit.getTargets());
		for (ICompilationUnit unit : clonedCollection) {
			if (unit.getParent().getElementName().equals(delta.getElement().getElementName())) {
				processRemovedCompilationUnit(modelEvent, unit);
			}
		}
	}

	private Collection<ICompilationUnit> cloneCollection(Collection<ICompilationUnit> targets) {
		Collection<ICompilationUnit> result = new ArrayList<ICompilationUnit>();
		for (ICompilationUnit iCompilationUnit : targets) {
			result.add(iCompilationUnit);
		}
		return result;
	}

	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();
	}

}
