package se.unlogic.standardutils.collections;

import se.unlogic.standardutils.dao.enums.Order;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Comparator;


public class MethodComparator<T> implements Comparator<T> {

	protected Method method;
	protected final Order order;
	
	public MethodComparator(Class<? extends T> clazz, String methodName, Order order){
		
		Method[] methods = clazz.getDeclaredMethods();
		
		for(Method method : methods){
			
			if(method.getName().equals(methodName) && Comparable.class.isAssignableFrom(method.getReturnType()) && method.getParameterTypes().length == 0){
				
				this.method = method;
				break;
			}
		}
		
		if(method == null){
			
			throw new RuntimeException("No method named " + methodName + " returning a comparable class and taking no paramaters found in " + clazz);
		}
		
		this.order = order;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public int compare(T o1, T o2) {
		
		try {

			if(order == Order.ASC){
				
				return ((Comparable)method.invoke(o1)).compareTo(method.invoke(o2));

			}else{
				
				return ((Comparable)method.invoke(o2)).compareTo(method.invoke(o1));
			}
			
			
		} catch (IllegalArgumentException e) {

			throw new RuntimeException(e);
			
		} catch (IllegalAccessException e) {

			throw new RuntimeException(e);
			
		} catch (InvocationTargetException e) {

			throw new RuntimeException(e);
		}		
	}
}
