package org.b4zv4lidator.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;

public final class B4zV4lidatorUtil {

	private final static Logger LOGGER = Logger.getLogger(B4zV4lidatorUtil.class.getName());

	private B4zV4lidatorUtil() {
	}

	public static Annotation getAnnotationRuleFromField(final Object obj, final Field field,
			final Class<? extends Annotation> annotation) {

		Annotation anno = null;
		try {
			final Annotation annoField = field.getAnnotation(annotation);
			final Annotation annoMethod = obj.getClass()
					.getDeclaredMethod(B4zV4lidatorUtil.getMethod(obj, field).getName()).getAnnotation(annotation);
			anno = Objects.nonNull(annoField) ? annoField : annoMethod;
		} catch (SecurityException | NoSuchMethodException e) {
			e.printStackTrace();
		}
		return anno;
	}

	public static Method getMethod(final Object obj, final Field field) {
		Method method = null;
		final String fieldName = field.getName();
		final String methodName = "get" + StringUtils.capitalize(fieldName);
		try {
			method = obj.getClass().getDeclaredMethod(methodName.trim(), new Class<?>[0]);
			method.setAccessible(true);
		} catch (NoSuchMethodException | SecurityException e) {
			final String[] splitedReturnType = field.getType().getName().split("\\.");
			final int splitedReturnTypeLength = splitedReturnType.length - 1;
			B4zV4lidatorUtil.LOGGER.severe("The attribute " + fieldName
					+ " cannot be validated because it has not a well formed getter method. This method should be like: \n\n\tpublic "
					+ splitedReturnType[splitedReturnTypeLength] + " " + methodName + "() {\n" + "\n"
					+ "		return this." + fieldName + ";\n" + "	}");
		}
		return method;
	}

	public static Boolean hasGroups(final List<String> groups1, final String[] groups2) {

		return !Collections.disjoint(groups1, Arrays.asList(groups2));
	}

}