package com.zcxk.core.common.support;

import com.zcxk.core.common.annotation.EnumCheck;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author Andy
 * @description: Enum Check Validator
 * @date 2021/7/16
 * @version V1.0
 **/
public class EnumCheckValidator implements ConstraintValidator<EnumCheck, String> {

    private Class<? extends Enum<?>> enumClass;
    private String enumMethod;


    @Override
    public void initialize(EnumCheck enumCheck) {
        enumMethod = enumCheck.enumMethod();
        enumClass  = enumCheck.enumClass();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return Boolean.FALSE;
        }
        if (enumClass == null || enumMethod == null) {
            return Boolean.FALSE;
        }
        Class<?> valueClass = value.getClass();

        try {
            Method method = enumClass.getMethod(enumMethod, valueClass);
            if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
                throw new RuntimeException(String.format("%s method return is not boolean type in the %s class", enumMethod, enumClass));
            }

            if (!Modifier.isStatic(method.getModifiers())) {
                throw new RuntimeException(String.format("%s method is not static method in the %s class", enumMethod, enumClass));
            }

            Boolean result = (Boolean) method.invoke(null, value);
            return result == null ? false : result;
        } catch (NoSuchMethodException | SecurityException e) {
            throw new RuntimeException(String.format("This %s(%s) method does not exist in the %s", enumMethod, valueClass, enumClass), e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
