package com.palacesun.masking.tools.sm4fpe;

import java.security.Security;
import java.util.ArrayList;
import java.util.Random;
import java.util.regex.Pattern;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class SM4FPEEmail extends SM4FPEBase {
   static ArrayList<SM4FPEEntity> emailEntities = new ArrayList();
   private static Pattern emailPrefix;
   private static Pattern emailSuffix;

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

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

   public static boolean isemail(String email) {
      boolean result = false;
      email = email.trim();
      if (email.length() < 6) {
         return result;
      } else {
         String[] emailsuffix = email.split("@");
         if (emailsuffix.length == 2) {
            result = true;
         }

         if (!result) {
            return result;
         } else {
            if (null == emailPrefix || null == emailSuffix) {
               emailPrefix = Pattern.compile("^((?!_\\-\\.)[\\u4e00-\\u9fa5a-zA-Z0-9]+)([\\u4e00-\\u9fa5a-zA-Z0-9_\\-\\.]*)");
               emailSuffix = Pattern.compile("^((?!\\.$)(?!\\_$)(?!\\-$).)*$");
            }

            if (emailPrefix.matcher(emailsuffix[0]).find() && emailSuffix.matcher(emailsuffix[0]).matches() && emailPrefix.matcher(emailsuffix[1]).find() && emailSuffix.matcher(emailsuffix[1]).matches()) {
               result = true;
            } else {
               result = false;
            }

            return result;
         }
      }
   }

   String generateInputRandom(String input) {
      Random random = new Random();

      for(int i = 0; i < 10; ++i) {
         int index = random.nextInt(emailEntities.size());
         input = input + ((SM4FPEEntity)emailEntities.get(index)).getList().get(random.nextInt(((SM4FPEEntity)emailEntities.get(index)).getList().size()));
      }

      input = input + "@";

      for(int i = 0; i < 8; ++i) {
         int index = random.nextInt(emailEntities.size());
         input = input + ((SM4FPEEntity)emailEntities.get(index)).getList().get(random.nextInt(((SM4FPEEntity)emailEntities.get(index)).getList().size()));
      }

      input = input + ".";

      for(int i = 0; i < 5; ++i) {
         int index = random.nextInt(emailEntities.size());
         input = input + ((SM4FPEEntity)emailEntities.get(index)).getList().get(random.nextInt(((SM4FPEEntity)emailEntities.get(index)).getList().size()));
      }

      return input;
   }

   public int initTypes(String input, int m, SegmentType[] types, ArrayList<SM4FPEEntity> entities) throws Exception {
      String[] emailsuffix = input.split("@");
      if (emailsuffix.length == 2) {
         int dotIndex = emailsuffix[1].indexOf(".");
         if (dotIndex > 0) {
            int dotInInput = emailsuffix[0].length() + 1 + dotIndex;
            String inputBeforeDot = input.substring(0, dotInInput);
            int dataSegmentLen = super.initTypes(inputBeforeDot, inputBeforeDot.length(), types, entities);
            types[dataSegmentLen].type = 99999;
            types[dataSegmentLen].length = input.length() - inputBeforeDot.length();
            ++dataSegmentLen;
            return dataSegmentLen;
         } else {
            return super.initTypes(input, m, types, entities);
         }
      } else {
         return super.initTypes(input, m, types, entities);
      }
   }

   public static boolean check(String input) {
      return isemail(input);
   }

   static {
      Security.addProvider(new BouncyCastleProvider());

      try {
         emailEntities.add(new SM4FPEEntity(0, toArrayList(enCapitalChars), enCapitalCharsMap));
         emailEntities.add(new SM4FPEEntity(1, toArrayList(enSmallChars), enSmallCharsMap));
         emailEntities.add(new SM4FPEEntity(2, toArrayList(digitChars), digitCharsMap));
         emailEntities.add(new SM4FPEEntity(3, toArrayList(chineseChars), chineseCharsMap));
         checkDuplicate(emailEntities);
      } catch (RuntimeException e) {
         throw e;
      }
   }
}
