package kcg.imis.comn.validator;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.oro.text.perl.Perl5Util;
import org.springframework.validation.Errors;
import org.springframework.web.multipart.MultipartFile;
import org.springmodules.validation.commons.FieldChecks;

/**
  * @FileName : KcgFieldChecks.java
  * @Project : 국제해양프로젝트
  * @Date : 2018. 3. 29. 
  * @작성자 : Moon
  * @변경이력 : 
  * @프로그램 설명 :
 */
public class KcgFieldChecks extends FieldChecks {
	/**
	 * sericalVersion UID.
	 */
	private static final long serialVersionUID = -2911390948016164140L;

	/**
	 * <code>Log</code> used by this class.
	 */
	private static final Log LOGGER = LogFactory.getLog(FieldChecks.class);

	/**
	 * 파일 확장자 체크.
	 * 
	 * @param bean
	 *            The bean validation is being performed on.
	 * @param va
	 *            The <code>ValidatorAction</code> that is currently being
	 *            performed.
	 * @param field
	 *            field The <code>Field</code> object associated with the
	 *            current field being validated.
	 * @param errors
	 *            Errors The <code>Errors</code> object to add errors to if any
	 *            validation errors occur.
	 * @return <code>true</code> Valid. <code>false</code> inValid.
	 */
	public static boolean validateFileExt(final Object bean,
			final ValidatorAction va, final Field field, final Errors errors) {

		String value = extractValue(bean, field);
		String extStr = field.getVarValue("ext");
		try {
			String[] validExts;
			String regexp = "";
			if (!GenericValidator.isBlankOrNull(extStr)) {
				int loopIdx = 0;
				validExts = extStr.split(",");
				regexp = "\\.(";
				for (String s : validExts) {
					if (loopIdx > 0) {
						regexp += "|";
					}
					regexp += s;
					loopIdx++;
				}
				regexp += ")$";
			}
			
			Perl5Util matcher = null;
			try {
				
				matcher = new Perl5Util();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (value != null) {
				boolean isValid = matcher.match("/" + regexp + "/i", value);
				if (!GenericValidator.isBlankOrNull(value) && !isValid) {
					FieldChecks.rejectValue(errors, field, va);
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			KcgFieldChecks.LOGGER.error(e.getMessage(), e);
		}

		return true;
	}
	
	public static boolean validateStrRegex(final Object bean,
			final ValidatorAction va, final Field field, final Errors errors) {
		
		String value = FieldChecks.extractValue(bean, field);
		String idRegex = field.getVarValue("regex");
		
		if (!value.matches(idRegex)) {
			FieldChecks.rejectValue(errors, field, va);
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * 객체 내 프로퍼티의 값을 추출하여 반환한다.
	 * 
	 * <pre>
	 * FieldCheck.extractValue 메소드 Override.
	 * </pre>
	 * 
	 * @param bean
	 *            값을 추출할 대상 객체
	 * @param field
	 *            실제 값을 추출할 대상 객체의 프로퍼티
	 * @return bean.field가 갖고 있는 값
	 */
	protected static String extractValue(final Object bean, final Field field) {
        String value = null;

        if (bean == null) {
            return null;
        } else if (bean instanceof String) {
            value = (String) bean;
        } else {
            value = getValueAsString(bean, field.getProperty());
        }

        return value;
    }
	
    /**
     * 객체 내 프로퍼티의 값을 추출하여 반환한다.
     * 
     * <pre>
	 * ValidatorUtils.getValueAsString 메소드 커스터 마이징.
	 * </pre>
	 * 
	 * @param bean
	 *            bean 값을 추출할 대상 객체
	 * @param property
	 *            실제 값을 추출할 대상 객체의 프로퍼티
	 * @return bean.field가 갖고 있는 값
	 */
    public static String getValueAsString(final Object bean, final String property) {
        Object value = null;

        try {
            value = PropertyUtils.getProperty(bean, property);

		} catch (IllegalAccessException e) {
			Log log = LogFactory.getLog(ValidatorUtils.class);
			log.error(e.getMessage(), e);
		} catch (InvocationTargetException e) {
			Log log = LogFactory.getLog(ValidatorUtils.class);
			log.error(e.getMessage(), e);
		} catch (NoSuchMethodException e) {
			Log log = LogFactory.getLog(ValidatorUtils.class);
			log.error(e.getMessage(), e);
		}

        if (value == null) {
            return null;
        }

        if (value instanceof String[]) {
            return ((String[]) value).length > 0 ? value.toString() : "";

        } else if (value instanceof Collection) {
            return ((Collection) value).isEmpty() ? "" : value.toString();

        } else if (value instanceof MultipartFile) {
        	MultipartFile file = (MultipartFile) value;
			if (file.isEmpty()) {
        		return "";
        	} else {
        		return file.getOriginalFilename();
        	}
        } else {
            return value.toString();
        }

    }
}
