/* (C) 2022 YiRing, Inc. */
package com.yiring.common.validation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 枚举参数校验器
 *
 * @author Jim
 * @version 0.1
 * 2022/9/29 16:06
 */
public class EnumValueValidated implements ConstraintValidator<EnumValue, Object> {

    private boolean isRequire;
    private Set<String> strValues;
    private List<Integer> intValues;

    @Override
    public void initialize(EnumValue constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
        strValues = Set.of(constraintAnnotation.strValues());
        intValues = Arrays.stream(constraintAnnotation.intValues()).boxed().collect(Collectors.toList());
        isRequire = constraintAnnotation.isRequire();

        // 将枚举类的 name 转小写存入 strValues 里面，作为校验参数
        Optional
            .ofNullable(constraintAnnotation.enumClass())
            .ifPresent(e ->
                Arrays
                    .stream(e)
                    .forEach(c ->
                        Arrays.stream(c.getEnumConstants()).forEach(v -> strValues.add(v.toString().toLowerCase()))
                    )
            );
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null && !isRequire) {
            return true;
        }

        if (value instanceof String) {
            return strValues.contains(value);
        }
        if (value instanceof Integer) {
            return intValues.stream().anyMatch(e -> e.equals(value));
        }

        return false;
    }
}
