/*******************************************************************************
 * Copyright (c) 2007, 2008 SAP AG 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:
 * Kaloyan Raev, kaloyan.raev@sap.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.web.operations;

import static org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties.ABSTRACT_METHODS;
import static org.eclipse.jst.j2ee.internal.web.operations.INewFilterClassDataModelProperties.DESTROY;
import static org.eclipse.jst.j2ee.internal.web.operations.INewFilterClassDataModelProperties.DO_FILTER;
import static org.eclipse.jst.j2ee.internal.web.operations.INewFilterClassDataModelProperties.FILTER_MAPPINGS;
import static org.eclipse.jst.j2ee.internal.web.operations.INewFilterClassDataModelProperties.INIT;
import static org.eclipse.jst.j2ee.internal.web.operations.INewFilterClassDataModelProperties.INIT_PARAM;
import static org.eclipse.jst.j2ee.web.IServletConstants.DESTROY_SIGNATURE;
import static org.eclipse.jst.j2ee.web.IServletConstants.DO_FILTER_SIGNATURE;
import static org.eclipse.jst.j2ee.web.IServletConstants.FILTER_INIT_SIGNATURE;
import static org.eclipse.jst.j2ee.web.IServletConstants.METHOD_DESTROY;
import static org.eclipse.jst.j2ee.web.IServletConstants.METHOD_DO_FILTER;
import static org.eclipse.jst.j2ee.web.IServletConstants.METHOD_INIT;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_ANNOTATION_INIT_PARAM;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_FILTER_CHAIN;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_FILTER_CONFIG;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_IO_EXCEPTION;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_SERVLET_EXCEPTION;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_SERVLET_REQUEST;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_SERVLET_RESPONSE;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_WEB_FILTER;
import static org.eclipse.jst.j2ee.web.IServletConstants.QUALIFIED_ANNOTATION_DISPATCHER_TYPE;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jst.j2ee.internal.common.operations.Method;
import org.eclipse.jst.j2ee.webapplication.DispatcherType;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;

public class CreateFilterTemplateModel extends CreateWebClassTemplateModel {

	public static final String ATT_FILTER_NAME = "filterName"; //$NON-NLS-1$
	public static final String ATT_SERVLET_NAMES = "servletNames"; //$NON-NLS-1$
	public static final String ATT_DISPATCHER_TYPES= "dispatcherTypes"; //$NON-NLS-1$
	
	public static final int NAME = 0;
	public static final int VALUE = 1;
	public static final int DESCRIPTION = 2;

	public CreateFilterTemplateModel(IDataModel dataModel) {
		super(dataModel);
    }
    
	@Override
	public Collection<String> getImports() {
		Collection<String> collection = super.getImports();
		
		if (shouldGenInit()) {
			collection.add(QUALIFIED_FILTER_CONFIG);
			collection.add(QUALIFIED_SERVLET_EXCEPTION);
		}
		
		if (shouldGenDoFilter()) {
			collection.add(QUALIFIED_SERVLET_REQUEST);
			collection.add(QUALIFIED_SERVLET_RESPONSE);
			collection.add(QUALIFIED_FILTER_CHAIN);
			collection.add(QUALIFIED_IO_EXCEPTION);
			collection.add(QUALIFIED_SERVLET_EXCEPTION);
		}
		if (SERVLET_3.equals(getJavaEEVersion())){
			collection.add(QUALIFIED_WEB_FILTER);
			if (getInitParams()!= null && getInitParams().size()>0){
				collection.add(QUALIFIED_ANNOTATION_INIT_PARAM);
			}
			if (hasDispatchers()){
				collection.add(QUALIFIED_ANNOTATION_DISPATCHER_TYPE);
			}
		}
		
		return collection;
	}

	public String getFilterName() {
		return super.getDisplayName();
	}

	public boolean shouldGenInit() {
		return implementImplementedMethod(METHOD_INIT);
	}

	public boolean shouldGenDoFilter() {
		return implementImplementedMethod(METHOD_DO_FILTER);
	}

	public boolean shouldGenDestroy() {
		return implementImplementedMethod(METHOD_DESTROY);
	}

	public List<String[]> getInitParams() {
		return (List) dataModel.getProperty(INIT_PARAM);
	}

	public String getInitParam(int index, int type) {
		List<String[]> params = getInitParams();
		if (index < params.size()) {
			String[] stringArray = params.get(index);
			return stringArray[type];
		}
		return null;
	}

	public List<IFilterMappingItem> getFilterMappings() {
		return (List<IFilterMappingItem>) dataModel.getProperty(FILTER_MAPPINGS);
	}

	public IFilterMappingItem getFilterMapping(int index) {
		List<IFilterMappingItem> mappings = getFilterMappings();
		if (index < mappings.size()) {
		    return mappings.get(index);
		}
		return null;
	}
	
	public String getDispatcherList(IFilterMappingItem mapping) {
		List<String> list = new ArrayList<String>();
		
		int dispatchers = mapping.getDispatchers();
		if ((dispatchers & IFilterMappingItem.REQUEST) > 0) {
			list.add(DispatcherType.REQUEST_LITERAL.getLiteral());
        }
        if ((dispatchers & IFilterMappingItem.FORWARD) > 0) {
        	list.add(DispatcherType.FORWARD_LITERAL.getLiteral());
        }
        if ((dispatchers & IFilterMappingItem.INCLUDE) > 0) {
        	list.add(DispatcherType.INCLUDE_LITERAL.getLiteral());
        }
        if ((dispatchers & IFilterMappingItem.ERROR) > 0) {
        	list.add(DispatcherType.ERROR_LITERAL.getLiteral());
        }
        
        StringBuilder builder = new StringBuilder();
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
        	builder.append(iterator.next());
        	if (iterator.hasNext()) {
        		builder.append(","); //$NON-NLS-1$
        	}
        }
		
		return builder.toString();
	}
	
	public List<String> getDispatcherListWeb3(IFilterMappingItem mapping) {
		List<String> list = new ArrayList<String>();
		
		int dispatchers = mapping.getDispatchers();
		if ((dispatchers & IFilterMappingItem.REQUEST) > 0) {
            list.add("DispatcherType.REQUEST"); //$NON-NLS-1$
        }
        if ((dispatchers & IFilterMappingItem.FORWARD) > 0) {
            list.add("DispatcherType.FORWARD"); //$NON-NLS-1$
        }
        if ((dispatchers & IFilterMappingItem.INCLUDE) > 0) {
            list.add("DispatcherType.INCLUDE"); //$NON-NLS-1$
        }
        if ((dispatchers & IFilterMappingItem.ERROR) > 0) {
            list.add("DispatcherType.ERROR"); //$NON-NLS-1$
        }
        
		return list;
	}

	protected boolean implementImplementedMethod(String methodName) {
		if (dataModel.getBooleanProperty(ABSTRACT_METHODS)) {
			if (methodName.equals(METHOD_INIT))
				return dataModel.getBooleanProperty(INIT);
			else if (methodName.equals(METHOD_DO_FILTER))
				return dataModel.getBooleanProperty(DO_FILTER);
			else if (methodName.equals(METHOD_DESTROY))
				return dataModel.getBooleanProperty(DESTROY);
		}		
		return false;
	}
	
	@Override
	public Collection<Method> getUnimplementedMethods() {
		Collection<Method> unimplementedMethods = super.getUnimplementedMethods();
		Iterator<Method> iterator = unimplementedMethods.iterator();
		
		while (iterator.hasNext()) {
			Method method = iterator.next();
			if ((METHOD_INIT.equals(method.getName()) && FILTER_INIT_SIGNATURE.equals(method.getSignature())) || 
					(METHOD_DESTROY.equals(method.getName()) && DESTROY_SIGNATURE.equals(method.getSignature())) ||
					(METHOD_DO_FILTER.equals(method.getName()) && DO_FILTER_SIGNATURE.equals(method.getSignature()))) {
				iterator.remove();
			}
		}
		
		return unimplementedMethods;
	}
	
	public boolean hasDispatchers(){
		List<IFilterMappingItem> filterMappings = getFilterMappings();
		for (IFilterMappingItem filterMapping : filterMappings) {
			if (filterMapping.getDispatchersAsString().length()>0){
				return true;
			}
		}
		return false;
	}
	
	public Map<String, Object> getClassAnnotationParams() {
		Map<String, Object> result = new Hashtable<String, Object>();
		
		String dispName = getFilterName().trim();
		if (!dispName.equals(getClassName()) && (dispName.length() > 0))
			result.put(ATT_FILTER_NAME, dispName);
		
		String description = getDescription().trim();
		if (description.length() > 0)
			result.put(ATT_DESCRIPTION, description);
		
		List<IFilterMappingItem> filterMappings = getFilterMappings();
		List<String> urlMappings = new ArrayList<String>();
		List<String> servletNames = new ArrayList<String>();
		List<String> dispatcherTypes = new ArrayList<String>();
		for (IFilterMappingItem filterMapping : filterMappings) {
			List<String> dispatcherList = getDispatcherListWeb3(filterMapping);
			if (dispatcherList != null && dispatcherList.size()>0){
				for (String disp : dispatcherList) {
					if (!dispatcherTypes.contains(disp)){
						dispatcherTypes.add(disp);	
					}
				}
				
			}
			if (filterMapping.isUrlPatternType()) {
				urlMappings.add(filterMapping.getName());
			} else if (filterMapping.isServletNameType()) {
				servletNames.add(filterMapping.getName());
			}
		}
		if (urlMappings.size() > 0) {
			result.put(ATT_URL_PATTERNS, urlMappings);
		}
		if (dispatcherTypes.size() > 0) {
			result.put(ATT_DISPATCHER_TYPES, dispatcherTypes);
		}
		if (servletNames.size() > 0) {
			result.put(ATT_SERVLET_NAMES, servletNames);
		}
		
		
		List<String[]> initParams = getInitParams();
		if (initParams != null && initParams.size() > 0) {
			result.put(ATT_INIT_PARAMS, initParams);
		}

		return result;
	}
	
}

