package cd.casic.module.terminal.utils;

import cd.casic.module.terminal.common.ErrorMessage;
import cd.casic.module.terminal.common.holder.SpringHolder;
import cn.orionsec.kit.lang.utils.Arrays1;
import cn.orionsec.kit.lang.utils.io.Files1;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

/**
 * 验证器
 *
 * @author Jiahang Li
 * @version 1.0.0
 * @since 2023/7/18 11:23
 */
public class Valid extends cn.orionsec.kit.lang.utils.Valid {

    private static final Validator validator = SpringHolder.getBean(Validator.class);

    public static <T> T notNull(T object) {
        return notNull(object, ErrorMessage.PARAM_MISSING);
    }

    public static <T> T isNull(T object) {
        return isNull(object, ErrorMessage.PARAM_ERROR);
    }

    public static String notBlank(String s) {
        return notBlank(s, ErrorMessage.PARAM_MISSING);
    }

    public static <T extends Map<?, ?>> T notEmpty(T map) {
        return notEmpty(map, ErrorMessage.PARAM_MISSING);
    }

    public static <T extends Collection<?>> T notEmpty(T object) {
        return notEmpty(object, ErrorMessage.PARAM_MISSING);
    }

    public static void allNotNull(Object... objects) {
        if (objects != null) {
            for (Object t : objects) {
                notNull(t, ErrorMessage.PARAM_MISSING);
            }
        }
    }

    public static void allNotBlank(String... ss) {
        if (ss != null) {
            for (String s : ss) {
                notBlank(s, ErrorMessage.PARAM_MISSING);
            }
        }
    }

    public static void eq(Object o1, Object o2) {
        eq(o1, o2, ErrorMessage.INVALID_PARAM);
    }

    public static boolean isTrue(boolean s) {
        return isTrue(s, ErrorMessage.INVALID_PARAM);
    }

    public static boolean isFalse(boolean s) {
        return isFalse(s, ErrorMessage.INVALID_PARAM);
    }

    public static <T extends Comparable<T>> T gte(T t1, T t2) {
        return gte(t1, t2, ErrorMessage.INVALID_PARAM);
    }

    @SafeVarargs
    public static <T> T in(T t, T... ts) {
        notNull(t, ErrorMessage.INVALID_PARAM);
        notEmpty(ts, ErrorMessage.INVALID_PARAM);
        isTrue(Arrays1.contains(ts, t), ErrorMessage.INVALID_PARAM);
        return t;
    }

    /**
     * 验证枚举
     *
     * @param of  of method
     * @param obj obj
     * @param <T> param
     * @param <E> enum
     * @return enum
     */
    public static <T, E extends Enum<?>> E valid(Function<T, E> of, T obj) {
        return notNull(of.apply(obj), ErrorMessage.INVALID_PARAM);
    }

    /**
     * 验证对象
     *
     * @param obj    obj
     * @param groups groups
     * @param <T>    T
     * @return obj
     */
    public static <T> T valid(T obj, Class<?>... groups) {
        notNull(obj, ErrorMessage.PARAM_MISSING);
        // 验证对象
        Set<ConstraintViolation<T>> set = validator.validate(obj, groups);
        if (!set.isEmpty()) {
            throw new ConstraintViolationException(set);
        }
        return obj;
    }

    /**
     * 检查是否更新成功
     *
     * @param effect effect
     * @return effect
     */
    public static int version(int effect) {
        isTrue(effect > 0, ErrorMessage.DATA_MODIFIED);
        return effect;
    }

    /**
     * 检查路径是否合法化 即不包含 ./ ../
     *
     * @param path path
     */
    public static String checkNormalize(String path) {
        Valid.notBlank(path);
        Valid.isTrue(Files1.isNormalize(path), ErrorMessage.PATH_NOT_NORMALIZE);
        return Files1.getPath(path);
    }

}
