package com.chenyang.nse.bussiness.tools.encryption;

import com.chenyang.nse.bussiness.config.PropertiesLoaderUtils;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPEAddressUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPECellPhoneUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPECompanyUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPEEmailUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPEIdentityUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPENameUtil;
import com.chenyang.nse.bussiness.tools.encryption.sm4fpe.SM4FPETools;
import java.io.IOException;
import java.util.Objects;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;

public class EncProvider {
   public static final int DEF_KEY_SIZE = 128;
   public static final int DEF_KEY_SIZE_256 = 256;
   public static final int DEF_KEY_SIZE_192 = 192;
   private static Properties properties;
   private static String ENCRYPT_LABEL;
   private static String ENCRYPT_LABEL_SUFFIX;
   private static String ENCRYPT_LIKE_SPLIT;

   public static String generateKey(String type) throws Exception {
      if (type == null) {
         throw new IllegalArgumentException("type");
      } else {
         switch (type) {
            case "SM4":
            case "SM4_ECB":
            case "SM4_CBC":
            case "SM4_OFB":
            case "SM4_CFB":
            case "SM4_GCM":
            case "SM4_CCM":
               return SM4Util.generateKey();
            case "SM4_FPE":
               return SM4FPETools.generateKey();
            case "AES":
            case "AES128":
               return AesEncryptUtils.generaKey();
            case "AES256":
               return AesEncryptUtils.generaKeyTwo();
            case "AES192":
               return AesEncryptUtils.generaKeyThree();
            case "DES":
               return DESUtil.generateKey();
            case "3DES":
               return DES3Util.generateKey();
            default:
               if (type.startsWith("SM4_FPE")) {
                  return SM4FPETools.generateKey();
               } else {
                  throw new UnSupportedEncTypeException(type);
               }
         }
      }
   }

   public static String encryptEcb(String type, String key, String text, String isLike, String keepfirst, String encdigit, String twoindex) throws Exception {
      if (type == null) {
         throw new IllegalArgumentException("type");
      } else if (text == null) {
         return text;
      } else if (text.contains(ENCRYPT_LABEL)) {
         return text;
      } else {
         String encrypt;
         switch (type) {
            case "SM4":
               SM4Util.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
            case "SM4_ECB":
            case "SM4_CBC":
            case "SM4_OFB":
            case "SM4_CFB":
            case "SM4_GCM":
            case "SM4_CCM":
               encrypt = SM4Util.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex, type);
               break;
            case "SM4_FPE_IDENTITYNO":
               encrypt = SM4FPEIdentityUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "SM4_FPE_PHONE":
               encrypt = SM4FPECellPhoneUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "SM4_FPE_EMAIL":
               encrypt = SM4FPEEmailUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "SM4_FPE_NAME":
               encrypt = SM4FPENameUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "SM4_FPE_COMPANY_NAME":
               encrypt = SM4FPECompanyUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "SM4_FPE_ADDRESS":
               encrypt = SM4FPEAddressUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "AES":
            case "AES128":
            case "AES192":
            case "AES256":
               encrypt = AesEncryptUtils.encrypt(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "DES":
               encrypt = DESUtil.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
               break;
            case "3DES":
               encrypt = DES3Util.encryptEcb(key, text, isLike, keepfirst, encdigit, twoindex, "ECB");
               break;
            default:
               throw new UnSupportedEncTypeException(type);
         }

         if (Objects.equals(isLike, "0")) {
            if (StringUtils.isBlank(keepfirst)) {
               return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
            } else if (Objects.equals(keepfirst, "0")) {
               if (StringUtils.isBlank(encdigit)) {
                  return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
               } else if (Integer.parseInt(encdigit) < encrypt.length()) {
                  String prefix = encrypt.substring(0, Integer.parseInt(encdigit));
                  String enc = encrypt.substring(Integer.parseInt(encdigit));
                  return prefix + ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX;
               } else {
                  return encrypt + ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX;
               }
            } else if (Objects.equals(keepfirst, "1")) {
               if (StringUtils.isBlank(encdigit)) {
                  return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
               } else if (Integer.parseInt(encdigit) < encrypt.length()) {
                  String prefix = encrypt.substring(encrypt.length() - Integer.parseInt(encdigit));
                  String enc = encrypt.substring(0, encrypt.length() - Integer.parseInt(encdigit));
                  return ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX + prefix;
               } else {
                  return ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX + encrypt;
               }
            } else if (Objects.equals(keepfirst, "2")) {
               if (StringUtils.isNotBlank(encdigit)) {
                  if (Integer.parseInt(encdigit) + Integer.parseInt(twoindex) > encrypt.length()) {
                     return ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX + encrypt;
                  } else if (Integer.parseInt(encdigit) >= encrypt.length() && Integer.parseInt(twoindex) >= encrypt.length() && Integer.parseInt(encdigit) + Integer.parseInt(twoindex) >= encrypt.length()) {
                     return encrypt + ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX;
                  } else {
                     String prefix = encrypt.substring(0, Integer.parseInt(encdigit));
                     String enc = encrypt.substring(Integer.parseInt(encdigit), encrypt.length() - Integer.parseInt(twoindex));
                     String suffix = encrypt.substring(encrypt.length() - Integer.parseInt(twoindex));
                     return prefix + ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX + suffix;
                  }
               } else {
                  return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
               }
            } else {
               return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
            }
         } else if (StringUtils.isBlank(keepfirst)) {
            return (ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL);
         } else if (Objects.equals(keepfirst, "0")) {
            if (StringUtils.isBlank(encdigit)) {
               return (ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL);
            } else if (Integer.parseInt(encdigit) < encrypt.length()) {
               String prefix = encrypt.substring(0, Integer.parseInt(encdigit));
               String enc = encrypt.substring(Integer.parseInt(encdigit));
               return prefix + (ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL);
            } else {
               return encrypt + ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX;
            }
         } else if (Objects.equals(keepfirst, "1")) {
            if (StringUtils.isBlank(encdigit)) {
               return (ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL);
            } else if (Integer.parseInt(encdigit) < encrypt.length()) {
               String prefix = encrypt.substring(encrypt.length() - Integer.parseInt(encdigit));
               String enc = encrypt.substring(0, encrypt.length() - Integer.parseInt(encdigit));
               return (ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL) + prefix;
            } else {
               return ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX + encrypt;
            }
         } else if (Objects.equals(keepfirst, "2")) {
            if (StringUtils.isNotBlank(encdigit)) {
               if (Integer.parseInt(encdigit) + Integer.parseInt(twoindex) > encrypt.length()) {
                  return ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX + encrypt;
               } else if (Integer.parseInt(encdigit) >= encrypt.length() && Integer.parseInt(twoindex) >= encrypt.length()) {
                  return encrypt + ENCRYPT_LABEL + ENCRYPT_LABEL_SUFFIX;
               } else {
                  String prefix = encrypt.substring(0, Integer.parseInt(encdigit));
                  String enc = encrypt.substring(Integer.parseInt(encdigit), encrypt.length() - Integer.parseInt(twoindex));
                  String suffix = encrypt.substring(encrypt.length() - Integer.parseInt(twoindex));
                  return prefix + (ENCRYPT_LABEL + enc + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL) + suffix;
               }
            } else {
               return ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX;
            }
         } else {
            return (ENCRYPT_LABEL + encrypt + ENCRYPT_LABEL_SUFFIX).replaceAll(ENCRYPT_LIKE_SPLIT, ENCRYPT_LIKE_SPLIT + ENCRYPT_LABEL);
         }
      }
   }

   public static String decryptEcb(String type, String key, String text, String isLike, String keepfirst, String encdigit, String twoindex) throws Exception {
      if (type == null) {
         throw new IllegalArgumentException("type");
      } else if (text == null) {
         return text;
      } else {
         text = text.trim();
         if (text.equals("")) {
            return text;
         } else if (text.indexOf(ENCRYPT_LABEL) == -1) {
            return text;
         } else {
            text = text.replaceAll(ENCRYPT_LABEL, "");
            text = text.replaceAll(ENCRYPT_LABEL_SUFFIX, "");
            if (type != null) {
               type = type.toUpperCase();
            }

            try {
               switch (type) {
                  case "SM4":
                     return SM4Util.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_ECB":
                  case "SM4_GCM":
                  case "SM4_CBC":
                  case "SM4_OFB":
                  case "SM4_CFB":
                  case "SM4_CCM":
                     return SM4Util.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex, type);
                  case "SM4_FPE_IDENTITYNO":
                     return SM4FPEIdentityUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_FPE_PHONE":
                     return SM4FPECellPhoneUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_FPE_EMAIL":
                     return SM4FPEEmailUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_FPE_NAME":
                     return SM4FPENameUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_FPE_COMPANY_NAME":
                     return SM4FPECompanyUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "SM4_FPE_ADDRESS":
                     return SM4FPEAddressUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "AES":
                  case "AES128":
                  case "AES256":
                  case "AES192":
                     return AesEncryptUtils.decrypt(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "DES":
                     return DESUtil.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex);
                  case "3DES":
                     return DES3Util.decryptEcb(key, text, isLike, keepfirst, encdigit, twoindex, "ECB");
                  default:
                     throw new UnSupportedEncTypeException(type);
               }
            } catch (Exception var9) {
               return ENCRYPT_LABEL + text + ENCRYPT_LABEL_SUFFIX;
            }
         }
      }
   }

   public static void main(String[] args) {
      try {
         String type = "AES-256";
         String key = generateKey(type);
         System.out.println("密钥:" + key);
         String s = encryptEcb(type, key, "管理员", "0", "0", "0", "0");
         System.out.println("加密数据:" + s);
         String s1 = decryptEcb(type, key, s, "0", "0", "0", "0");
         System.out.println("解密数据:" + s1);
      } catch (Exception e) {
         e.printStackTrace();
      }

   }

   static {
      try {
         properties = PropertiesLoaderUtils.loadAllProperties("config.properties");
         ENCRYPT_LABEL = properties.get("encryption.label").toString();
         ENCRYPT_LABEL_SUFFIX = properties.get("encryption.label.suffix").toString();
         ENCRYPT_LIKE_SPLIT = properties.get("encryption.like.split").toString();
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}
