package com.palacesun.masking.tools.sm4fpe;

import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class SM4FPEAddress extends SM4FPEBase {
   public static final int LEVEL = 2;
   static ArrayList<SM4FPEEntity> addressEntities = new ArrayList();
   static String[] province2Chars;
   static String[] province3Chars;
   static ArrayList city2Chars;
   static String[] city3Chars;
   static String[] city4Chars;
   static char[] excludeChars;
   static char[] addressKeysChars;
   static String[] addressKeysStr;
   static ArrayList chineseList;
   static HashMap province2CharsMap;
   static HashMap province3CharsMap;
   static HashMap city2CharsMap;
   static HashMap city3CharsMap;
   static HashMap city4CharsMap;
   static HashMap chineseListMap;
   static HashMap addressKeysCharsMap;
   private static Pattern chineseAddressPattern;
   private static Pattern chineseAddressPatternFirstThree;

   public String encryptEcb(String hexKey, String a) throws Exception {
      String out = this.encrypt(hexKey, a, addressEntities);
      return out;
   }

   public String decryptEcb(String hexKey, String input) throws Exception {
      String out = this.decrypt(hexKey, input, addressEntities);
      return out;
   }

   public static boolean isChineseAddress(String address, int level) {
      boolean result = false;
      address = address.replaceAll("[^一-龥]", "");
      if (address.length() >= 6) {
         if (null == chineseAddressPatternFirstThree) {
            chineseAddressPatternFirstThree = Pattern.compile("[\\u4e00-\\u9fa5]{3}.*");
         }

         if (chineseAddressPatternFirstThree.matcher(address).matches()) {
            if (null == chineseAddressPattern) {
               List<Object> list = toArrayList(province3Chars);
               list.addAll(toArrayList(province2Chars));
               list.addAll(toArrayList(city4Chars));
               list.addAll(toArrayList(city3Chars));
               list.addAll(city2Chars);
               list.addAll(toArrayList(addressKeysChars));
               list.addAll(toArrayList(excludeChars));
               if (list.size() > 0) {
                  StringBuilder pattern = new StringBuilder();

                  for(Object str : list) {
                     String s = String.valueOf(str);
                     pattern.append(s);
                     pattern.append("|");
                  }

                  pattern.deleteCharAt(pattern.length() - 1);
                  chineseAddressPattern = Pattern.compile(pattern.toString());
               }
            }

            Matcher matcher = chineseAddressPattern.matcher(address);

            int num;
            for(num = 0; matcher.find(); ++num) {
            }

            if (num != 0 && num >= level) {
               result = true;
            }
         }
      }

      return result;
   }

   public static boolean check(String input) {
      return isChineseAddress(input, 2);
   }

   public static ArrayList<SM4FPEEntity> getSm4FPEEntities() {
      return addressEntities;
   }

   static {
      Security.addProvider(new BouncyCastleProvider());
      province2Chars = new String[]{"安徽", "香港", "福建", "贵州", "台湾", "陕西", "重庆", "广西", "河北", "澳门", "山西", "江苏", "吉林", "河南", "四川", "天津", "新疆", "内蒙", "宁夏", "浙江", "甘肃", "湖南", "辽宁", "江西", "湖北", "广东", "西藏", "海南", "山东", "青海", "云南"};
      province3Chars = new String[0];
      city2Chars = new ArrayList();
      city3Chars = new String[0];
      city4Chars = new String[0];
      excludeChars = new char[]{'省', '市', '区', '路'};
      addressKeysChars = new char[]{'座', '楼', '苑', '店', '乡', '厦', '居', '里', '屯', '园', '馆', '坊', '场', '巷', '所', '道', '舍', '庭', '斋', '村', '号', '室', '街', '条', '县', '墅', '弄', '寓', '层', '庄', '同', '堂', '院', '学'};
      StringBuilder resultBuilder = new StringBuilder();

      for(String province : province2Chars) {
         resultBuilder.append(province);
      }

      String excludeProvince = resultBuilder.toString();
      chineseList = excludeChars(toArrayList(chineseChars), excludeChars);
      chineseList = excludeChars(chineseList, addressKeysChars);
      chineseList = excludeChars(chineseList, excludeProvince.toCharArray());
      province2CharsMap = new HashMap();

      for(int i = 0; i < province2Chars.length; ++i) {
         province2CharsMap.put(province2Chars[i], i);
      }

      province3CharsMap = new HashMap();

      for(int i = 0; i < province3Chars.length; ++i) {
         province3CharsMap.put(province3Chars[i], i);
      }

      city2CharsMap = new HashMap();

      for(int i = 0; i < city2Chars.size(); ++i) {
         city2CharsMap.put(city2Chars.get(i), i);
      }

      city3CharsMap = new HashMap();

      for(int i = 0; i < city3Chars.length; ++i) {
         city3CharsMap.put(city3Chars[i], i);
      }

      city4CharsMap = new HashMap();

      for(int i = 0; i < city4Chars.length; ++i) {
         city4CharsMap.put(city4Chars[i], i);
      }

      addressKeysCharsMap = new HashMap();

      for(int i = 0; i < addressKeysChars.length; ++i) {
         addressKeysCharsMap.put(addressKeysChars[i], i);
      }

      chineseListMap = new HashMap();

      for(int i = 0; i < chineseList.size(); ++i) {
         chineseListMap.put(chineseList.get(i), i);
      }

      try {
         addressEntities.add(new SM4FPEEntity(0, toArrayList(province3Chars), province3CharsMap));
         addressEntities.add(new SM4FPEEntity(1, toArrayList(province2Chars), province2CharsMap));
         addressEntities.add(new SM4FPEEntity(2, toArrayList(city4Chars), city4CharsMap));
         addressEntities.add(new SM4FPEEntity(3, toArrayList(city3Chars), city3CharsMap));
         addressEntities.add(new SM4FPEEntity(4, city2Chars, city2CharsMap));
         addressEntities.add(new SM4FPEEntity(5, toArrayList(enCapitalChars), enCapitalCharsMap));
         addressEntities.add(new SM4FPEEntity(6, toArrayList(enSmallChars), enSmallCharsMap));
         addressEntities.add(new SM4FPEEntity(7, toArrayList(digitChars), digitCharsMap));
         addressEntities.add(new SM4FPEEntity(8, toArrayList(addressKeysChars), addressKeysCharsMap));
         addressEntities.add(new SM4FPEEntity(9, chineseList, chineseListMap));
         addressEntities.add(new SM4FPEEntity(10, otherChineseChars, otherChineseCharsMap));
         checkDuplicate(addressEntities);
      } catch (RuntimeException e) {
         throw e;
      }
   }
}
