/*******************************************************************************
 * Copyright (c) 2009 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.ws.jaxws.dom.runtime.persistence.serializer;

import java.util.TreeSet;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.ws.jaxws.dom.runtime.DomUtil;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebServiceProject;
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.IAnnotationSerializer;
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsDefaultsCalculator;
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsWorkspaceResource;
import org.eclipse.jst.ws.jaxws.dom.runtime.util.ParamValueComparator;
import org.eclipse.jst.ws.jaxws.utils.ContractChecker;
import org.eclipse.jst.ws.jaxws.utils.annotations.AnnotationFactory;
import org.eclipse.jst.ws.jaxws.utils.annotations.AnnotationGeneratorException;
import org.eclipse.jst.ws.jaxws.utils.annotations.AnnotationWriter;
import org.eclipse.jst.ws.jaxws.utils.annotations.IAnnotation;
import org.eclipse.jst.ws.jaxws.utils.annotations.IParamValuePair;
import org.eclipse.jst.ws.jaxws.utils.annotations.IValue;
import org.eclipse.jst.ws.jaxws.utils.logging.ILogger;
import org.eclipse.jst.ws.jaxws.utils.logging.Logger;

/**
 * Base class for DOM adapters that listen to changes in DOM objects and applies it
 * to the underlying java class. Extenders should implement <code>getAnnotation()</code>
 * method to provide the {@link IAnnotation} instance to be saved to java class.
 * 
 * @author Georgi Vachkov
 */
public abstract class AbstractSerializerAdapter extends AdapterImpl implements IAnnotationSerializer
{
	private final JaxWsWorkspaceResource resource;
	private final DomUtil util = new DomUtil();
	private final JaxWsDefaultsCalculator defCalc = new JaxWsDefaultsCalculator();
	
	/**
	 * Constructor
	 * @param resource
	 * @throws NullPointerException in case <code>resource</code> is <code>null</code>
	 */
	public AbstractSerializerAdapter(final JaxWsWorkspaceResource resource) 
	{
		ContractChecker.nullCheckParam(resource, "resource");//$NON-NLS-1$
		
		this.resource = resource;
	}
	
	@Override
	public void notifyChanged(final Notification msg)
	{
		if (!resource.isSaveEnabled() || msg.isTouch()) {
			return;
		}
		
		if (msg.getEventType() != Notification.SET && msg.getEventType() != Notification.UNSET) {
			return;
		}
		
		if (checkValue(msg)) {
			save(msg);
		}
	}
	
	/**
	 * Default value check - works only for String values, trims the
	 * new value checks for <code>null</code> and if it is not null puts the
	 * value to the object and returns <code>true</code> otherwise <code>false</code>
	 * @param msg
	 * @return <code>true</code> in case the value is valid
	 */
	protected boolean checkValue(final Notification msg)
	{
		EObject obj = (EObject)getTarget();
		final String newValue = getNewStringValue(msg);
		if (newValue==null) {			
			return revertValue(obj, msg);
		}
		
		// this call is needed cause newValue might be trimmed
		putValue(obj, (EStructuralFeature)msg.getFeature(), newValue);
		return true;
	}
	
	public void save(final Notification msg)
	{
		boolean processed = false;
		try {
			final IAnnotation<? extends IJavaElement> annotation = getAnnotation();
			if (annotation == null) {
				return;
			}
			
			if (annotation.getParamValuePairs().size()==0 && !isAnnotationRequired()) {
				getAnnotationWriter().remove(annotation);
			} else {
				getAnnotationWriter().update(annotation);
			}
			processed = true;
		} 
		catch (AnnotationGeneratorException e) {
			logger().logError(e.getMessage(), e);
		} 
		catch (CoreException e) {
			logger().logError(e.getMessage(), e);
		}
		finally {
			if(!processed) {
				revertValue((EObject)getTarget(), msg);
			}
		}
	}
	
	protected abstract IAnnotation<? extends IJavaElement> getAnnotation() throws JavaModelException;
	protected abstract boolean isAnnotationRequired();
	
	@Override
	public boolean isAdapterForType(Object type)
	{
	    return IAnnotationSerializer.class==type;
	}
	
	protected JaxWsWorkspaceResource resource()	{
		return resource;
	}
	
	protected DomUtil util() {
		return util;
	}
	
	protected JaxWsDefaultsCalculator defCalc()	{
		return defCalc;
	}
	
	protected AnnotationWriter getAnnotationWriter()
	{
		return AnnotationWriter.getInstance();
	}

	protected IParamValuePair createParamValue(String param, String value)
	{
		final IValue iValue = AnnotationFactory.createStringValue(value);
		return AnnotationFactory.createParamValuePairValue(param, iValue);
	}
	
	protected IParamValuePair createParamValue(String param, boolean value)
	{
		final IValue iValue = AnnotationFactory.createBooleanValue(value);
		return AnnotationFactory.createParamValuePairValue(param, iValue);
	}
	
	protected IType findType(final EObject object, final String typeFQName) throws JavaModelException
	{
		EObject webProject = object.eContainer();
		while(!(webProject instanceof IWebServiceProject) && webProject!=null) {
			webProject = webProject.eContainer();
		}
		
		if (webProject==null) {
			return null;
		}

		final String projectName = ((IWebServiceProject)webProject).getName();
		final IJavaProject javaProject = resource.javaModel().getJavaProject(projectName);		
		return javaProject.findType(typeFQName);
	}
	
	/**
	 * Reads the new string value from <code>msg</code>. 
	 * @param msg
	 * @return <code>null</code> if the value is empty string or <code>null</code>, otherwise the trimmed string value.
	 */
	protected String getNewStringValue(final Notification msg) 
	{
		final String newValue = (msg.getNewStringValue() == null) ? null : msg.getNewStringValue().trim();
		if (newValue != null && newValue.length() > 0) {
			return newValue;
		}
		
		return null;
	}
	
	/**
	 * Reverts the current value for the changed feature to the old value and returns <code>false</code>
	 * @param obj the object to be reverted
	 * @param msg the message
	 * @return always returns false
	 */
	protected boolean revertValue(final EObject obj, final Notification msg)
	{
		putValue(obj, (EStructuralFeature)msg.getFeature(), msg.getOldValue());
		return false;
	}
	
	/**
	 * Puts the <code>newValue</code> to the changed feature.
	 * @param obj the object to be updated
	 * @param msg the notification message
	 * @param newValue the new value to be put
	 */
	protected void putValue(final EObject obj, final EStructuralFeature feature, final Object newValue)
	{
		try {
			obj.eSetDeliver(false);
			obj.eSet(feature, newValue);
		} finally {
			obj.eSetDeliver(true);
		}
	}
	
	protected TreeSet<IParamValuePair> createParamValueSortedTreeSet()
	{
		return new TreeSet<IParamValuePair>(new ParamValueComparator());
	}
	
	private ILogger logger()
	{
		return new Logger();
	}
}
