/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */

package org.eclipse.osbp.runtime.common.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.osbp.runtime.common.annotations.AsKanbanState;
import org.eclipse.osbp.runtime.common.annotations.CreateAt;
import org.eclipse.osbp.runtime.common.annotations.CreateBy;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.annotations.Filter;
import org.eclipse.osbp.runtime.common.annotations.HistorizedObject;
import org.eclipse.osbp.runtime.common.annotations.OnKanbanCard;
import org.eclipse.osbp.runtime.common.annotations.Range;
import org.eclipse.osbp.runtime.common.annotations.UpdateAt;
import org.eclipse.osbp.runtime.common.annotations.UpdateBy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BeanUtils {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtils.class);

	public static List<Field> getAllFilteringFields(Class<?> clazz) {
		List<Field> result = new ArrayList<>();

		for (Field field : getAllFields(clazz)) {
			if (field.isAnnotationPresent(Range.class) || field.isAnnotationPresent(Filter.class)) {
				result.add(field);
			}
		}

		return result;
	}
	
	public static List<Field> getAllFields(Class<?> clazz, Class<? extends Annotation> annotation) {
		List<Field> result = new ArrayList<>();

		for (Field field : getAllFields(clazz)) {
			if (field.isAnnotationPresent(annotation)) {
				result.add(field);
			}
		}

		return result;
	}
	
	/**
	 * Returns a single field for the class and annotation.
	 * 
	 * @param clazz
	 * @param annotation
	 * @return
	 *
	 *@throws IllegalStateException if more then 1 field found
	 */
	public static Field getField(Class<?> clazz, Class<? extends Annotation> annotation) {
		List<Field> result = new ArrayList<>();

		for (Field field : getAllFields(clazz)) {
			if (field.isAnnotationPresent(annotation)) {
				result.add(field);
			}
		}
		
		if(result.size() > 1) {
			throw new IllegalStateException("More then one field found with given annotation " + annotation);
		}

		return result.isEmpty() ? null : result.get(0);
	}

	/**
	 * Returns all filtering fields recurse to the defined depth.
	 * 
	 * @param clazz
	 * @param depth
	 * @return
	 */
	public static List<Field> getAllFilteringFieldsRecurse(Class<?> clazz, int depth) {
		List<Field> result = new ArrayList<>();
		if (depth == -1) {
			return result;
		}

		for (Field field : getAllFields(clazz)) {
			if (field.isAnnotationPresent(Range.class) || field.isAnnotationPresent(Filter.class)) {
				result.add(field);
			} else if (field.isAnnotationPresent(DomainReference.class)) {
				result.addAll(getAllFilteringFieldsRecurse(field.getType(), depth--));
			}
		}

		return result;
	}

	/**
	 * Returns all property ids (eg: person.country.isocode) recurse to the
	 * defined depth.
	 * 
	 * @param clazz
	 * @param depth
	 * @return
	 */
	public static List<String> getAllFilteringProperties(Class<?> clazz, int depth) {
		List<String> result = new ArrayList<>();
		if (depth == -1) {
			return result;
		}

		return internalGetAllFilteringProperties(null, clazz, depth);
	}

	private static List<String> internalGetAllFilteringProperties(String currentPath, Class<?> clazz, int depth) {
		List<String> result = new ArrayList<>();
		if (depth == -1) {
			return result;
		}

		String newPath = currentPath;
		int newDepth = depth - 1;

		if (currentPath == null) {
			newPath = "";
		}

		for (Field field : getAllFields(clazz)) {
			if (field.isAnnotationPresent(Range.class) || field.isAnnotationPresent(Filter.class)) {
				result.add(toPath(newPath, field.getName()));
			} else if (field.isAnnotationPresent(DomainReference.class)) {
				result.addAll(
						internalGetAllFilteringProperties(toPath(newPath, field.getName()), field.getType(), newDepth));
			}
		}

		return result;
	}

	private static String toPath(String currentPath, String fieldName) {
		if (currentPath == null || currentPath.trim().equals("")) {
			return fieldName;
		} else {
			return currentPath + "." + fieldName;
		}
	}

	public static List<Field> getAllFields(Class<?> clazz) {
		if (clazz == null) {
			return null;
		}

		List<Field> result = new ArrayList<>();
		try {
			result.addAll(Arrays.asList(clazz.getDeclaredFields()));
		} catch (SecurityException e) {
			LOGGER.warn("{}", e);
		}

		Class<?> superClass = clazz.getSuperclass();
		if (superClass != null) {
			List<Field> temp = getAllFields(superClass);
			result.addAll(temp);
		}
		return result;
	}

	/**
	 * Returns the enum literals of the field annotated with AsKanbanState. Or
	 * null.
	 * 
	 * @param clazz
	 * @return
	 */
	public static <T> T[] getKanbanStateEnumLiterals(Class<?> clazz) {
		if (clazz == null) {
			return null;
		}

		@SuppressWarnings("unchecked")
		Class<T> enumx = (Class<T>) getAllFields(clazz).stream().filter(f -> f.isAnnotationPresent(AsKanbanState.class))
				.findFirst().map(f -> f.getType()).orElse(null);
		if (enumx != null && enumx.isEnum()) {
			return enumx.getEnumConstants();
		}
		return null;
	}

	/**
	 * Returns the enum literals of the field annotated with AsKanbanState. Or
	 * null.
	 * 
	 * @param clazz
	 * @return
	 */
	public static List<String> getKanbanVisibleOnCardProperties(Class<?> clazz) {
		if (clazz == null) {
			return null;
		}

		return getAllFields(clazz).stream().filter(f -> f.isAnnotationPresent(OnKanbanCard.class))
				.map(f -> f.getName()).collect(Collectors.toList());
	}

	/**
	 * Returns the state value of the given itemId.
	 * 
	 * @param itemId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getKanbanState(Object itemId) {
		Field stateField = getAllFields(itemId.getClass()).stream()
				.filter(f -> f.isAnnotationPresent(AsKanbanState.class)).findFirst().orElse(null);
		if (stateField != null) {
			return (T) DtoUtils.getValue(itemId, stateField.getName());
		}

		return null;
	}

	public static Class<?> getNestedFieldType(Class<?> clazz, String dotedPath) {
		Field field = getNestedField(clazz, dotedPath);
		return field != null ? field.getType() : null;
	}

	public static Field getNestedField(Class<?> clazz, String dotedPath) {

		String[] tokens = dotedPath.split("\\.");

		Field field = null;
		Class<?> fieldType = clazz;
		for (String token : tokens) {
			field = getField(fieldType, token);
			if (field == null) {
				return null;
			}

			fieldType = field.getType();
		}

		return field;
	}

	public static Field getField(Class<?> clazz, String name) {
		if (clazz == null) {
			return null;
		}
		Field field = null;
		try {
			field = clazz.getDeclaredField(name);
		} catch (SecurityException e) {
			LOGGER.warn("{}", e);
		} catch (NoSuchFieldException e) {
		}

		if (field == null) {
			Class<?> superClass = clazz.getSuperclass();
			if (superClass != null) {
				field = getField(superClass, name);
			}
		}
		return field;
	}

	public static boolean isBoolean(Class<?> clazz, String propertyId) {
		Class<?> type = getNestedFieldType(clazz, propertyId);
		return type == Boolean.class || type == Boolean.TYPE;
	}

	public static boolean isDate(Class<?> clazz, String propertyId) {
		Class<?> type = getNestedFieldType(clazz, propertyId);
		return Date.class.isAssignableFrom(type);
	}

	public static boolean isDecimal(Class<?> clazz, String propertyId) {
		Class<?> type = getNestedFieldType(clazz, propertyId);
		return type != String.class && type != Boolean.class && type != Boolean.TYPE
				&& (type.isPrimitive() || Number.class.isAssignableFrom(type));
	}

	public static boolean isString(Class<?> clazz, String propertyId) {
		Class<?> type = getNestedFieldType(clazz, propertyId);
		return type == String.class;
	}

	public static boolean isAnnotationPresent(Class<?> clazz, String nestedPropertyId,
			Class<? extends Annotation> annotation) {
		Field field = getNestedField(clazz, nestedPropertyId);
		if (field == null) {
			return false;
		}
		return field.isAnnotationPresent(annotation);
	}
	
	/**
	 * Returns true, if {@link HistorizedObject} annotation is present.
	 * @param clazz
	 * @return
	 */
	public static boolean isHistorized(Class<?> clazz) {
		Class<?> type = clazz;
		while(type != null) {
			if(type.isAnnotationPresent(HistorizedObject.class)){
				return true;
			}
			type = type.getSuperclass();
		}
		return false;
	}
	
	public static void setCreateUser(Object bean, String user){
		List<Field> fields = getAllFields(bean.getClass(), CreateBy.class);
		for(Field field : fields) {
			setter(bean, user, field);
		}
	}
	
	public static void setUpdateUser(Object bean, String user){
		List<Field> fields = getAllFields(bean.getClass(), UpdateBy.class);
		for(Field field : fields) {
			setter(bean, user, field);
		}
	}

	private static void setter(Object bean, Object obj, Field field) {
		try {
			BeanInfo info = Introspector.getBeanInfo(bean.getClass());
			for (PropertyDescriptor desc : info.getPropertyDescriptors()) {
				if (desc.getName().equalsIgnoreCase(field.getName())) {
					Method method = desc.getWriteMethod();
					method.invoke(bean, obj);
					break;
				}
			}
		} catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			LOGGER.error("{}", e);
		}
	}
	
	public static void setCreateAt(Object bean, Date date){
		List<Field> fields = getAllFields(bean.getClass(), CreateAt.class);
		for(Field field : fields) {
			setter(bean, date, field);
		}
	}
	
	public static void setUpdateAt(Object bean, Date date){
		List<Field> fields = getAllFields(bean.getClass(), UpdateAt.class);
		for(Field field : fields) {
			setter(bean, date, field);
		}
	}

	public static String getCreateUser(Object bean){
		List<Field> fields = getAllFields(bean.getClass(), CreateBy.class);
		for(Field field : fields) {
			try {
				field.setAccessible(true);
				return (String)field.get(bean);
			} catch (IllegalArgumentException | IllegalAccessException e) {
				LOGGER.error("{}", e);
			}
		}
		return null;
	}
	
	public static String getUpdateUser(Object bean){
		List<Field> fields = getAllFields(bean.getClass(), UpdateBy.class);
		for(Field field : fields) {
			try {
				field.setAccessible(true);
				return (String)field.get(bean);
			} catch (IllegalArgumentException | IllegalAccessException e) {
				LOGGER.error("{}", e);
			}
		}
		return null;
	}
	
	public static Date getCreateAt(Object bean){
		List<Field> fields = getAllFields(bean.getClass(), CreateAt.class);
		for(Field field : fields) {
			try {
				field.setAccessible(true);
				return (Date)field.get(bean);
			} catch (IllegalArgumentException | IllegalAccessException e) {
				LOGGER.error("{}", e);
			}
		}
		return null;
	}
	
	public static Date getUpdateAt(Object bean){
		List<Field> fields = getAllFields(bean.getClass(), UpdateAt.class);
		for(Field field : fields) {
			try {
				field.setAccessible(true);
				return (Date) field.get(bean);
			} catch (IllegalArgumentException | IllegalAccessException e) {
				LOGGER.error("{}", e);
			}
		}
		return null;
	}
}
