package com.ssj.framework.core.util;

import com.ssj.framework.basic.utils.EncryptUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.util.TextUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 
 * 类名称：PasswordUtil<br>
 * 类描述：账户密码工具类<br>
 * @version v1.0
 *
 */
public class PasswordUtil {
    private static final String DEFAULT_PWD = "123456";
    private static final String DEFAULT_PUBLIC_SALT = PropertiesUtil.getValue("public_salt");

    //public static final String CHECK_FAIL_MESSAGE = "密码长度不少于8位，且密码中至少包含数字、字母和符号";
    public static final String CHECK_FAIL_MESSAGE = "密码强度不符合规则";

    // 含有数字
    private static String CONTAIN_DIGIT_REGEX = ".*[0-9].*";
    // 包含字母
    private static String CONTAIN_LETTER_REGEX = ".*[a-zA-z].*";

    /**
     * 初始化密码 默认为：123456
     * @param salt
     * @return
     */
    public static String initPassword(String salt) {
        // 先使用MD5对默认密码hash一次
        String encyptPwd = encryptPassword(DEFAULT_PWD);
        // 对hash过的密码掺入盐值再次hash
        return encryptPassword(encyptPwd, salt);
    }

    /**
     * 初始化密码
     * @param md5Pwd md5加密的密码
     * @param salt
     * @return
     */
    public static String initPassword(String md5Pwd, String salt) {
        // 对hash过的密码掺入盐值再次hash
        return encryptPassword(md5Pwd, salt);
    }
    /**
     * 通过MD5加密密码
     * @param plainPwd
     * @return
     */
    public static String encryptPassword(String plainPwd) {
        return EncryptUtil.getMD5String(plainPwd).toString();
    }

    /**
     * 通过MD5加密 密码+盐
     * @param pwd 密码
     * @param salt 密码盐
     * @return
     */
    public static String encryptPassword(String pwd, String salt) {
        // 使用MD5对密码和盐值hash
        return Base64.encodeBase64String(EncryptUtil.getMD5String(pwd + salt + DEFAULT_PUBLIC_SALT).getBytes());
    }

    /**
     * 生成随机私盐值
     * @return
     */
    public static String generateSalt() {
        return EncryptUtil.getMD5String(EncryptUtil.getUUIDString());
    }

    /**
     * 校验密码是否正确
     * @param pwd 经过md5加密的密码
     * @param dbPwd 数据库用户密码
     * @param salt 用户密码私盐
     * @return
     */
    public static boolean checkPwd(String pwd, String dbPwd, String salt) {
        boolean result = false;
        if (StringUtil.isNotBlank(pwd)) {
            if (dbPwd.equals(encryptPassword(pwd, salt))) {
                result = true;
            }
        }
        return result;
    }

    /**
     * 校验口令复杂度
     *
     * @param password
     * @return
     */
    public static boolean checkRule(String password) {
        if (TextUtils.isEmpty(password)) {
            return false;
        }
        return checkRule2(password);
    }

    public static boolean checkRule1(String password) {
        //密码不少于6位不多于12位，必须为数字和字母组合
        if (password.length() >= 6 && password.length() <= 12) {
            if (hasDigit(password) && hasLetter(password)) {
                return true;
            }
        }
        return false;
    }

    public static boolean checkRule2(String password) {
        //密码长度不少于8位，且密码中至少包含数字、字母和符号
        String regexp = "^(?=.*\\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*￥])[\\da-zA-Z~!@#$%^&*￥]{8,}$";
        Pattern pattern = Pattern.compile(regexp);
        Matcher matcher = pattern.matcher(password);
        return matcher.find();
    }

    /**
     * 包含数字
     * @param ret
     * @return
     */
    public static boolean hasDigit(String ret) {
        return ret.matches(CONTAIN_DIGIT_REGEX );
    }

    /**
     * 包含字母
     * @param ret
     * @return
     */
    public static boolean hasLetter(String ret) {
        return ret.matches(CONTAIN_LETTER_REGEX);
    }

    /**
     * 校验新旧密码是否一致
     *
     * @param newPassword
     * @param oldPassword
     * @param pwdSalt
     * @return
     */
    public static boolean verificationPassword(String newPassword, String oldPassword, String pwdSalt) {
        if (StringUtil.isBlank(newPassword) || StringUtil.isBlank(oldPassword) || StringUtil.isBlank(pwdSalt)) {
            return false;
        }
        String encryptionPassword = PasswordUtil.initPassword(newPassword, pwdSalt);
        if (oldPassword.equals(encryptionPassword)) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println(PasswordUtil.initPassword("123456", "f0bbd3f145ea1ffec88762e1b492a0af"));
    }
}
