package com.bonus.core.common.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.constant.RetCodeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
import java.util.function.Function;

public class JavaxValidateUtils {
   private static final Logger log = LoggerFactory.getLogger(JavaxValidateUtils.class);

   public static <T> void validate(T object) {
      Set<ConstraintViolation<T>> violations = validator().validate(object, new Class[0]);
      if (!violations.isEmpty()) {
         ConstraintViolation<T> firstViolation = (ConstraintViolation)CollUtil.getFirst(violations);
         throw new ServiceException(messageFormat(firstViolation), RetCodeEnum.CORE_PARAM_ERROR.getKey());
      }
   }

   public static <T> void validate(T object, Function<T, Boolean> additionalCondition) {
      Set<ConstraintViolation<T>> violations = validator().validate(object, new Class[0]);
      if (!violations.isEmpty()) {
         ConstraintViolation<T> firstViolation = (ConstraintViolation)CollUtil.getFirst(violations);
         throw new ServiceException(messageFormat(firstViolation), RetCodeEnum.CORE_PARAM_ERROR.getKey());
      } else if (additionalCondition != null && !(Boolean)additionalCondition.apply(object)) {
         throw new ServiceException("请传入有效参数", RetCodeEnum.CORE_PARAM_ERROR.getKey());
      }
   }

   private static <T> String messageFormat(ConstraintViolation<T> firstViolation) {
      String fieldName = firstViolation.getPropertyPath().toString();
      String fieldDesc;
      String errorMsg;
      if (fieldName.contains(".")) {
         errorMsg = (String)CollUtil.getLast(StrUtil.split(firstViolation.getPropertyPath().toString(), "."));
         fieldDesc = LogUtil.getDescOfField(firstViolation.getLeafBean().getClass(), errorMsg);
      } else {
         fieldDesc = LogUtil.getDescOfField(firstViolation.getRootBeanClass(), firstViolation.getPropertyPath().toString());
      }

      errorMsg = firstViolation.getMessage();
      if ((StrUtil.isBlank(errorMsg) || "请传入有效参数".equals(errorMsg)) && firstViolation.getConstraintDescriptor() != null) {
         String messageTemplate = firstViolation.getConstraintDescriptor().getMessageTemplate();
         log.error(messageTemplate);
      }

      if (StrUtil.isBlank(errorMsg)) {
         errorMsg = "请传入有效参数";
      }

      log.error(fieldDesc + errorMsg + ": " + fieldName + "=" + String.valueOf(firstViolation.getInvalidValue()));
      return fieldName + ": " + errorMsg;
   }

   private static Validator validator() {
      return (Validator)SpringContextHolder.getBean(Validator.class);
   }
}
