/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */

package org.eclipse.osbp.autowirehelper;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osbp.autowirehelper.AutowireHelper.LocalResourceAccess;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmFeature;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmParameterizedTypeReference;
import org.eclipse.xtext.common.types.JvmPrimitiveType;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.common.types.TypesPackage;
import org.eclipse.xtext.common.types.util.RawSuperTypes;
import org.eclipse.xtext.resource.IReferenceDescription;
import org.eclipse.xtext.ui.editor.findrefs.IReferenceFinder;
import org.eclipse.xtext.util.IAcceptor;
import org.eclipse.xtext.xbase.lib.StringExtensions;

import com.google.inject.Inject;

/**
 * Helper class to collect all properties for a given JvmType.
 */
@SuppressWarnings("restriction")
public class JvmTypeProperties {

	@Inject
	private IReferenceFinder referenceFinder;

	/**
	 * Normalizes the method name.
	 * 
	 * @param simpleName
	 * @return
	 */
	public static String toPropertyName(String simpleName) {
		if (simpleName == null) {
			return null;
		}
		String tempName = null;
		if (isSetter(simpleName)) {
			tempName = StringExtensions.toFirstLower(simpleName.replaceFirst(
					"set", ""));
		} else if (isGetter(simpleName)) {
			if (simpleName.startsWith("get")) {
				tempName = StringExtensions.toFirstLower(simpleName
						.replaceFirst("get", ""));
			} else {
				tempName = StringExtensions.toFirstLower(simpleName
						.replaceFirst("is", ""));
			}
		}
		return tempName;
	}

	public static boolean isGetter(String simpleName) {
		if (simpleName == null) {
			return false;
		}
		return simpleName.startsWith("get") || simpleName.startsWith("is");
	}

	public static boolean isSetter(String simpleName) {
		return simpleName != null && simpleName.startsWith("set");
	}

	/**
	 * Calculates the operation infos for the given type.
	 * 
	 * @param type
	 * @return
	 */
	public static Map<String, Info> getOperationInfos(JvmDeclaredType type) {
		return getOperationInfos(type, null);
	}

	/**
	 * Calculates the operation infos for the given info.
	 * 
	 * @param info
	 * @return
	 */
	public static Map<String, Info> getOperationInfos(Info info) {

		JvmType type = null;
		if (info.isMany()) {
			type = info.getParameterizedType();
		} else {
			type = info.getType();
		}

		Map<String, Info> result = null;
		if (type instanceof JvmDeclaredType) {
			result = getOperationInfos((JvmDeclaredType) type);
		} else {
			result = new HashMap<String, JvmTypeProperties.Info>();
		}
		// apply the info as a parent
		for (Info temp : result.values()) {
			temp.setParent(info);
		}

		return result;
	}

	/**
	 * Calculates the operation infos for the given type.
	 * 
	 * @param type
	 * @param filterName
	 *            - is used to filter only methods property names matching the
	 *            filter name.
	 * @return
	 */
	public static Map<String, Info> getOperationInfos(JvmDeclaredType type,
			String filterName) {
		Map<String, Info> infos = new HashMap<String, Info>();
		for (JvmFeature feature : type.getAllFeatures()) {
			if (!(feature instanceof JvmOperation)) {
				continue;
			}

			JvmOperation operation = (JvmOperation) feature;
			if (operation.getVisibility() != JvmVisibility.PUBLIC) {
				continue;
			}

			if (!isSetter(operation.getSimpleName())
					&& operation.getParameters().size() > 1) {
				continue;
			}

			String propertyName = toPropertyName(operation.getSimpleName());
			if (propertyName == null) {
				continue;
			}

			if (filterName != null && !filterName.equals(propertyName)) {
				continue;
			}

			if (operation.getSimpleName().equals("getClass")) {
				continue;
			}

			if (!isGetter(operation.getSimpleName())
					&& !isSetter(operation.getSimpleName())) {
				continue;
			}

			String id = calcId(operation.getDeclaringType(),
					operation.getSimpleName());
			if (!infos.containsKey(id)) {
				Info info = new Info();
				info.id = id;
				info.name = propertyName;
				infos.put(id, info);
			}

			Info info = infos.get(id);
			if (isGetter(operation.getSimpleName())) {
				info.getter = operation;
			} else {
				if (!propertyName.equals("dirty")) {
					info.setter = operation;
				}
			}
		}

		// apply readonly and create descriptions
		for (Info info : infos.values()) {
			if (info.getter == null) {
				continue;
			}
			if (info.setter == null) {
				info.readonly = true;
			}
		}

		for (JvmFeature member : type.getAllFeatures()) {
			if (member instanceof JvmField) {
				JvmField field = (JvmField) member;
				String id = calcFieldId(field.getDeclaringType(),
						field.getSimpleName());
				if (infos.containsKey(id)) {
					Info info = infos.get(id);
					info.setField(field);
					info.type = field.getType().getType();
					info.primitive = info.type instanceof JvmPrimitiveType
							|| info.type.getQualifiedName().equals(
									String.class.getName());

					// collect all super types and check if collection is part
					// of them
					Set<String> superTypes = new RawSuperTypes()
							.collectNames(info.type);
					for (String typeName : superTypes) {
						if (typeName.equals(Collection.class.getName())) {
							info.many = true;
							break;
						}
					}

					if (info.many) {
						JvmParameterizedTypeReference typeRef = (JvmParameterizedTypeReference) field
								.getType();
						if (!typeRef.getArguments().isEmpty()) {
							info.parameterizedType = typeRef.getArguments()
									.get(0).getType();
						}
					}
				}
			}
		}
		return infos;
	}

	/**
	 * Normalizes the name.
	 * 
	 * @param declaringType
	 * @param simpleName
	 * @return
	 */
	public static String calcId(JvmDeclaredType declaringType, String simpleName) {
		String tempName = toPropertyName(simpleName);
		if (tempName == null) {
			return null;
		}

		return declaringType.getQualifiedName() + ":" + tempName;
	}

	/**
	 * Normalizes the name.
	 * 
	 * @param declaringType
	 * @param simpleName
	 * @return
	 */
	public static String calcFieldId(JvmDeclaredType declaringType,
			String simpleName) {
		return declaringType.getQualifiedName() + ":" + simpleName;
	}

	/**
	 * Finds all sub types of the given dtoType.
	 */
	public Set<URI> findSubTypes(JvmType dtoType, ResourceSet rs) {
		Set<URI> result = new HashSet<>();
		Set<URI> jvmTypeURIs = new HashSet<>();
		jvmTypeURIs.add(EcoreUtil.getURI(dtoType));
		IAcceptor<IReferenceDescription> acceptor = e -> {
			if (e.getEReference() == TypesPackage.Literals.JVM_PARAMETERIZED_TYPE_REFERENCE__TYPE) {
				if (e.getSourceEObjectUri().fragment()
						.endsWith("/@superTypes.0")) {
					URI uri = e.getSourceEObjectUri();
					result.add(URI.createURI(uri.toString().replace(
							"/@superTypes.0", "")));
				}
			}
		};
		referenceFinder.findAllReferences(jvmTypeURIs, new LocalResourceAccess(
				rs), acceptor, null);
		return result;
	}

	public static class Info implements Comparable<Info> {

		/**
		 * Can by any object that requested the info. For instance a YBeanSlot,
		 * an Entity, a JvmField,... The root should only be set for the top
		 * most parent.
		 */
		private Object root;
		/**
		 * The parent which requested this instance of info.
		 */
		private Info parent;
		private String id;
		private String name;
		private boolean readonly;
		private boolean primitive;
		private JvmOperation getter;
		private JvmOperation setter;
		private JvmField field;
		private JvmType type;
		private JvmType parameterizedType;
		private boolean many;

		public Info getParent() {
			return parent;
		}

		public void setParent(Info parent) {
			this.parent = parent;
		}

		public Info getTopParent() {
			if (getParent() != null) {
				return getParent().getTopParent();
			}
			return this;
		}

		public Object getRoot() {
			if (this.root == null && getParent() != null) {
				return getParent().getRoot();
			}
			return root;
		}

		public void setRoot(Object root) {
			this.root = root;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public boolean isReadonly() {
			return readonly;
		}

		public void setReadonly(boolean readonly) {
			this.readonly = readonly;
		}

		public JvmOperation getGetter() {
			return getter;
		}

		public void setGetter(JvmOperation getter) {
			this.getter = getter;
		}

		public JvmOperation getSetter() {
			return setter;
		}

		public void setSetter(JvmOperation setter) {
			this.setter = setter;
		}

		public JvmField getField() {
			return field;
		}

		public void setField(JvmField field) {
			this.field = field;
		}

		public boolean isPrimitive() {
			return primitive;
		}

		public void setPrimitive(boolean primitive) {
			this.primitive = primitive;
		}

		public JvmType getType() {
			return type;
		}

		public void setType(JvmType type) {
			this.type = type;
		}

		public boolean isMany() {
			return many;
		}

		public void setMany(boolean many) {
			this.many = many;
		}

		public JvmType getParameterizedType() {
			return parameterizedType;
		}

		public void setParameterizedType(JvmType parameterizedType) {
			this.parameterizedType = parameterizedType;
		}

		/**
		 * Returns true, if the info has an annotation matching the given
		 * annotationType.
		 * 
		 * @param annotationType
		 * @return
		 */
		public boolean hasAnnotation(Class<?> annotationType) {
			if (field == null) {
				return false;
			}
			for (JvmAnnotationReference annotation : field.getAnnotations()) {
				if (annotation.getAnnotation().getQualifiedName()
						.equals(annotationType.getName())) {
					return true;
				}
			}
			return false;
		}

		/**
		 * Returns the dot'ed attribute path for this info and its parents. For
		 * instance <code>person.address.name</code>.
		 * 
		 * @return
		 */
		public String getAttributePath() {
			return getAttributePath(parent, name);
		}

		protected String getAttributePath(Info parent, String postFix) {
			if (parent != null) {
				String temp = parent.getAttributePath();
				return temp + "." + postFix;
			} else {
				return postFix;
			}
		}

		@Override
		public int compareTo(Info other) {
			if (name == null || other == null) {
				return -1;
			}
			return name.compareTo(other.getName());
		}
	}
}
