package com.sun.identity.shared.encode;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.BitSet;

public class URLEncDec {
   private static final String UTF_8 = "UTF-8";
   private static final int CASE_DIFF = 32;
   private static final BitSet DONT_NEED_ENCODING = new BitSet(256);

   public static String encode(String s) {
      String ret = null;

      try {
         ret = encode(s, "UTF-8");
      } catch (UnsupportedEncodingException var3) {
      }

      return ret;
   }

   public static String decode(String s) {
      String ret = null;

      try {
         ret = decode(s, "UTF-8");
      } catch (UnsupportedEncodingException var3) {
      }

      return ret;
   }

   private static String encode(String s, String enc) throws UnsupportedEncodingException {
      boolean needToChange = false;
      boolean wroteUnencodedChar = false;
      int maxBytesPerChar = 10;
      StringBuilder out = new StringBuilder(s.length());
      ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
      OutputStreamWriter writer = new OutputStreamWriter(buf, enc);

      for (int i = 0; i < s.length(); i++) {
         int c = s.charAt(i);
         if (DONT_NEED_ENCODING.get(c)) {
            if (c == 32) {
               c = 43;
               needToChange = true;
            }

            out.append((char)c);
            wroteUnencodedChar = true;
         } else {
            try {
               if (wroteUnencodedChar) {
                  writer = new OutputStreamWriter(buf, enc);
                  wroteUnencodedChar = false;
               }

               writer.write(c);
               if (c >= 55296 && c <= 56319 && i + 1 < s.length()) {
                  int d = s.charAt(i + 1);
                  if (d >= 56320 && d <= 57343) {
                     writer.write(d);
                     i++;
                  }
               }

               writer.flush();
            } catch (IOException e) {
               buf.reset();
               continue;
            }

            byte[] ba = buf.toByteArray();

            for (byte b : ba) {
               out.append('%');
               char ch = Character.forDigit(b >> 4 & 15, 16);
               if (Character.isLetter(ch)) {
                  ch = (char)(ch - ' ');
               }

               out.append(ch);
               ch = Character.forDigit(b & 15, 16);
               if (Character.isLetter(ch)) {
                  ch = (char)(ch - ' ');
               }

               out.append(ch);
            }

            buf.reset();
            needToChange = true;
         }
      }

      return needToChange ? out.toString() : s;
   }

   private static String decode(String s, String enc) throws UnsupportedEncodingException {
      boolean needToChange = false;
      StringBuilder sb = new StringBuilder();
      int numChars = s.length();
      int i = 0;
      if (enc.isEmpty()) {
         throw new UnsupportedEncodingException("URLDecoder: empty string enc parameter");
      }

      while (i < numChars) {
         char c = s.charAt(i);
         switch (c) {
            case '%':
               try {
                  byte[] bytes = new byte[(numChars - i) / 3];
                  int pos = 0;

                  while (i + 2 < numChars && c == '%') {
                     bytes[pos++] = (byte)Integer.parseInt(s.substring(i + 1, i + 3), 16);
                     i += 3;
                     if (i < numChars) {
                        c = s.charAt(i);
                     }
                  }

                  if (i < numChars && c == '%') {
                     throw new IllegalArgumentException("URLDecoder: Incomplete trailing escape (%) pattern");
                  }

                  sb.append(new String(bytes, 0, pos, enc));
               } catch (NumberFormatException e) {
                  throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - " + e.getMessage());
               }

               needToChange = true;
               break;
            case '+':
               sb.append(' ');
               i++;
               needToChange = true;
               break;
            default:
               sb.append(c);
               i++;
         }
      }

      return needToChange ? sb.toString() : s;
   }

   static {
      for (int i = 97; i <= 122; i++) {
         DONT_NEED_ENCODING.set(i);
      }

      for (int var1 = 65; var1 <= 90; var1++) {
         DONT_NEED_ENCODING.set(var1);
      }

      for (int var2 = 48; var2 <= 57; var2++) {
         DONT_NEED_ENCODING.set(var2);
      }

      DONT_NEED_ENCODING.set(32);
      DONT_NEED_ENCODING.set(45);
      DONT_NEED_ENCODING.set(95);
      DONT_NEED_ENCODING.set(46);
      DONT_NEED_ENCODING.set(42);
   }
}
