package com.ssm.core.utils;


import com.ssm.config.AESConfig;
import com.ssm.manage.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ObjectUtils;
import org.apache.tomcat.util.buf.HexUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * AES 是一种可逆加密算法，对用户的敏感信息加密处理
 * 对原始数据进行AES加密后，在进行Base64编码转化；
 * 正确
 */
@Slf4j
public class AESUtils {
    // 算法名称
    static final String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    static final String algorithmStr = "AES/CBC/NoPadding";

    public static byte[] initKey(String key){
        byte[] b = key.getBytes();
        byte[] keys = new byte[16];
        System.arraycopy(b,0,keys,0,b.length);
        return keys;
    }

    public static String encrypt(String content) {
        try {
            Cipher cipher = Cipher.getInstance(algorithmStr);
            int blockSize = cipher.getBlockSize();

            byte[] dataBytes = content.getBytes("utf-8");
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

            SecretKeySpec keyspec = new SecretKeySpec(initKey("demaygood"), KEY_ALGORITHM);
            IvParameterSpec ivspec = new IvParameterSpec("0102030405060809".getBytes("utf-8"));

            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);
            return HexUtils.toHexString(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public static String decrypt(String content) throws Exception {
        try
        {
            byte[] encrypted1 = HexUtils.fromHexString(content);
            Cipher cipher = Cipher.getInstance(algorithmStr);
            SecretKeySpec keyspec = new SecretKeySpec(initKey("demaygood"), "AES");
            IvParameterSpec ivspec = new IvParameterSpec("0102030405060809".getBytes("utf-8"));

            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original,"utf-8");
            return originalString.replaceAll("\\s*","");
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /*
  * 加密
  * 1.构造密钥生成器
  * 2.根据ecnodeRules规则初始化密钥生成器
  * 3.产生密钥
  * 4.创建和初始化密码器
  * 5.内容加密
  * 6.返回字符串
  */
    public static String encode(String encodeRules, String content){
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen=KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            keygen.init(128, new SecureRandom(encodeRules.getBytes("utf-8")));
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
            byte [] byte_encode=content.getBytes("utf-8");
            //9.根据密码器的初始化方式--加密：将数据加密
            byte [] byte_AES=cipher.doFinal(byte_encode);
            //10.将加密后的数据转换为字符串
            //这里用Base64Encoder中会找不到包
            //解决办法：
            //在项目的Build path中先移除JRE System Library，再添加库JRE System Library，重新编译后就一切正常了。
            String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
            //11.将字符串返回
            return AES_encode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //如果有错就返加nulll
        return null;
    }
    /*
     * 解密
     * 解密过程：
     * 1.同加密1-4步
     * 2.将加密后的字符串反纺成byte[]数组
     * 3.将加密内容解密
     */
    public static String AESDncode(String encodeRules,String content){
        try {
            //1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen= KeyGenerator.getInstance("AES");
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            keygen.init(128, new SecureRandom(encodeRules.getBytes("utf-8")));
            //3.产生原始对称密钥
            SecretKey original_key=keygen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte [] raw=original_key.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKey key=new SecretKeySpec(raw, "AES");
            //6.根据指定算法AES自成密码器
            Cipher cipher=Cipher.getInstance("AES");
            //7.初始化密码器，第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作，第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            //8.将加密并编码后的内容解码成字节数组
            byte [] byte_content= new BASE64Decoder().decodeBuffer(content);
            /*
             * 解密
             */
            byte [] byte_decode=cipher.doFinal(byte_content);
            String AES_decode=new String(byte_decode,"utf-8");
            return AES_decode;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        //如果有错就返加null
        return null;
    }


    public static void main(String[] args) throws Exception {
//        log.error("定时任务添加测试");
//        Map map = new HashMap();
//        map.put("sss","sss");
//        QuartzManage.addTask("TestClassStart","TestClassStartGroup","TestClassStartTrigger",
//                "TestClassStartTriggerGroup", TestClassTask.class,30,map);

//        QuartzManage.addTask("storeMemberStart","storeMemberStartGroup","storeMemberStartTrigger",
//                "storeMemberStartTriggerGroup", TestClassTask.class,"10 * * * * ? *",map);

//        try {
//            // 1、创建一个JobDetail实例，指定Quartz
//            JobDetail jobDetail = JobBuilder.newJob(TestClassTask.class)
//                    // 任务执行类
//                    .withIdentity("job1_1", "jGroup1")
//                    // 任务名，任务组
//                    .build();
//            // 2、创建Trigger
//            SimpleScheduleBuilder builder = SimpleScheduleBuilder
//                    .simpleSchedule()
//                    // 设置执行次数
//                    .repeatSecondlyForTotalCount(100);
//            Trigger trigger = TriggerBuilder.newTrigger()
//                    .withIdentity("trigger1_1", "tGroup1").startNow()
//                    .withSchedule(builder).build();
//            // 3、创建Scheduler
//            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//            scheduler.start();
//            // 4、调度执行
//            scheduler.scheduleJob(jobDetail, trigger);
//            try {
//                Thread.sleep(60000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//
//            scheduler.shutdown();
//
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }


//        System.out.println(encrypt(""));
//        System.out.println(new SnowflakeUtil(new Random().nextInt(1023)).nextId());
        System.out.println(encrypt("13662780023"));//加密
        System.out.println("++++++"+decrypt("330da8084205eec7bd29ef4af0f151a8"));//解密
        System.out.println(DateUtils.ymParse("2021-03"));
        String memberNum = "0077700003";
        System.out.println(memberNum.substring(memberNum.length() - 5,memberNum.length()));
        float a = 2;
        float b = 3;
        System.out.println(BigDecimalUtils.div(BigDecimalUtils.bigDecimal("0"), BigDecimalUtils.bigDecimal("2000")));
//        System.out.println(encrypt(null));
//        Boolean f = DateUtils.compare(DateUtils.YMParse("2020-07-08 00:00:00"),new Date()) < 0;
//        System.out.println(f);
//        System.out.println(new Date());
//        System.out.println(decrypt("f6cf08eebf20564424f72be84e74260ac2e24761dc029a04cc68513ed03598f2ba34c37bda43c879194e389e8153d29293ec2211a4d4279f150fc3e03934699009742b795d53b1f643777b1374ba4bbc00cd24b5e2da9454831992c560c949a9097f4179fb68610a40a0cb7ba03d3247462a285f83f9d84d5ee70612ed24e264518fefe6e7452bf3c744ed7f07a502f128b3d4878e6d31f8f1bbdad1c694d651"));
//        String num = "";
//        String YM = "202008";
//        int mm = Integer.parseInt("202008100".substring(6)) + 1;
//        if (mm < 10){
//            num = "00" + mm;
//        }else if (mm < 100){
//            num = "0" + mm;
//        }else {
//            num = String.valueOf(mm);
//        }
//        System.out.println(YM + num);

    }
}