package info.bukova.isspst.sort;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ReflectionTools {

	private static String capitalizeFirstLetter(String string)
	{
		String result = string.substring(0,1).toUpperCase() + string.substring(1, string.length());
		return result;
	}
	
	public static String getGetterName(String propertyName)
	{
		String getterName = "get" + ReflectionTools.capitalizeFirstLetter(propertyName);
		return getterName;
	}
	
	public static String getBoolGetterName(String propertyName)
	{
		String getterName = "is" + ReflectionTools.capitalizeFirstLetter(propertyName);
		return getterName;
	}
	
	public static Method getGetterMethod(Object bean, String propertyName)
	{
		Class<?> beanClass = bean.getClass();
		
		try
		{
			return beanClass.getMethod(ReflectionTools.getGetterName(propertyName));
		}
		catch(Throwable t)
		{
			// ignore
		}
		
		try
		{
			return beanClass.getMethod(ReflectionTools.getBoolGetterName(propertyName));
		}
		catch(Throwable t)
		{
			// ignore
		}
		
		throw new IllegalArgumentException("Not getter method found for '" + propertyName + "', bean: " + bean);
	}
	
	public static List<String> getEntityFields(Class<?> clazz) {
		BeanInfo beanInfo;
		try {
			beanInfo = Introspector.getBeanInfo(clazz);
		} catch (IntrospectionException e) {
			return null;
		}
	    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
	    List<String> properties = new ArrayList<String>();
	    for (PropertyDescriptor pd : pds) {
	    	if (!(pd.getName().equals("password") || pd.getName().equals("class") || pd.getName().equals("id") || pd.getName().equals("valid"))) {
	    		properties.add(pd.getName());
	    	}
	    }
	    
	    return properties;
	}
	
	public static List<String> getEntityFields(Object entity) {
		if (entity == null) {
			return null;
		}
		
		return getEntityFields(entity.getClass());
	}
	
	public static List<Field> getFields(Object entity) {
		if (entity == null) {
			return null;
		}
		
		return getFields(entity.getClass());
	}
	
	public static List<Field> getFields(Class<?> clazz) {
		List<Field> ret = new ArrayList<Field>();
		
		ret.addAll(Arrays.asList(clazz.getDeclaredFields()));
		if (!clazz.getSuperclass().equals(Object.class)) {
			ret.addAll(getFields(clazz.getSuperclass()));
		}
		
		return ret;
	}
}
