package com.zm.order.tool.server.utils;

import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * 订单中心常用方法工具类
 *
 * <p>
 *      继承StringUtils，集成了父类的方法。
 *      扩展一些自身系统使用的一些方法，有些方法做了一些比较便捷的扩展，用于日常开发
 *      比如：一些判空方法，本身不存在直接判断是否不为空，每次都需要手动的取反，有时候会忘记，比较头疼
 *      逐步封装一些较为简单，但比较好用的方法，支持开发人员更便捷的开发
 * </p>
 *
 * @author nianchang
 * @date 2022/05/25 11:02 上午
 */
public final class OrderCommonUtils extends StringUtils {

    /**
     * 判断字符串是否不为空
     *
     * <p>
     *      指定传入类型是String
     *      如果字符串是null或者""，都判定为空
     * </p>
     *
     * @param str 传入的参数
     * @return true || false
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 按照指定规则拼接成字符串，去除尾部符号
     *
     * <p>
     *      多个对象按照指定规则进行连接，生成一个String对象
     *      static方法，确认内部的对象在每个线程副本中的内存地址都是不同的，避免出现线程安全问题
     *      System.identityHashCode(): 查看对象的内存地址
     * </p>
     *
     * @param delimiter 分隔符
     * @param elements 需要拼接的数据集
     * @return 拼接结果，去除尾部拼接字符
     */
    public static String join(String delimiter, Object... elements) {
        if (delimiter == null || elements == null) {
            throw new NullPointerException("param is empty!");
        }
        StringJoiner joiner = new StringJoiner(delimiter);
        for (Object ele : elements) {
            joiner.add(String.valueOf(ele));
        }
        return joiner.toString();
    }

    /**
     * 比较是否相等
     *
     * <p>
     *      基本数据类型直接比较是否相等
     *      引用数据类型需要比较地址值与实际类型的equals方法
     *      equals会被自定义实现
     * </p>
     *
     * @param a 参数1
     * @param b 参数2
     * @return true || false
     */
    public static boolean equals(Object a, Object b) {
        return Objects.equals(a, b);
    }

    /**
     * 比较是否不相等
     *
     * <p>
     *      基本数据类型直接比较是否相等
     *      引用数据类型需要比较地址值与实际类型的equals方法
     *      equals会被自定义实现
     * </p>
     *
     * @param a 参数1
     * @param b 参数2
     * @return true || false
     */
    public static boolean notEquals(Object a, Object b) {
        return !(equals(a, b));
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     *      条件不成立，默认返回0
     * </p>
     *
     * @param obj 校验数据
     * @param val 目标结果
     * @return val || 0
     */
    public static Integer decideIfNotNull(Object obj, Integer val) {
        return (obj != null) ? val : 0;
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     *      条件不成立，默认返回0
     * </p>
     *
     * @param obj 校验数据
     * @param val 目标结果
     * @return val || 0
     */
    public static Long decideIfNotNull(Object obj, Long val) {
        return (obj != null) ? val : 0L;
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     *      条件不成立，默认返回now
     * </p>
     *
     * @param obj 校验数据
     * @param val 目标结果
     * @return val || now
     */
    public static Date decideIfNotNull(Object obj, Date val) {
        return (obj != null) ? val : new Date();
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     *      条件不成立，默认返回""
     * </p>
     *
     * @param obj 校验数据
     * @param val 目标结果
     * @return val || ""
     */
    public static String decideIfNotNull(Object obj, String val) {
        return (obj != null) ? val : "";
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     * </p>
     *
     * @param obj 校验数据
     * @param val0 目标结果
     * @param val1 目标结果
     * @return val0 || val1
     */
    public static <T> T decideIfNotEmpty(Object obj, T val0, T val1) {
        return !isEmpty(obj) ? val0 : val1;
    }

    /**
     * 三元运算符
     *
     * <p>
     *      根据校验规则，选择目标值
     * </p>
     *
     * @param bool 校验数据
     * @param val0 目标结果
     * @param val1 目标结果
     * @return val0 || val1
     */
    public static <T> T decideIfTrue(boolean bool, T val0, T val1) {
        return bool ? val0 : val1;
    }
}
