// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.asn1.x500.style;

import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.asn1.ASN1UniversalString;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.util.Strings;
import java.util.Enumeration;
import java.util.Hashtable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import java.util.Vector;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500NameStyle;

public class IETFUtils
{
    private static String unescape(final String s) {
        if (s.length() == 0) {
            return s;
        }
        if (s.indexOf(92) < 0 && s.indexOf(34) < 0) {
            return s.trim();
        }
        int n = 0;
        boolean b = false;
        final StringBuilder sb = new StringBuilder(s.length());
        int n2 = 0;
        if (s.charAt(0) == '\\' && s.charAt(1) == '#') {
            n2 = 2;
            sb.append("\\#");
        }
        boolean b2 = false;
        int length = 0;
        char c = '\0';
        for (int i = n2; i != s.length(); ++i) {
            final char char1 = s.charAt(i);
            if (char1 != ' ') {
                b2 = true;
            }
            if (char1 == '\"') {
                if (n == 0) {
                    b = !b;
                }
                else {
                    sb.append(char1);
                    n = 0;
                }
            }
            else if (char1 == '\\' && n == 0 && !b) {
                n = 1;
                length = sb.length();
            }
            else if (char1 != ' ' || n != 0 || b2) {
                if (n != 0 && isHexDigit(char1)) {
                    if (c != '\0') {
                        sb.append((char)(convertHex(c) * 16 + convertHex(char1)));
                        n = 0;
                        c = '\0';
                    }
                    else {
                        c = char1;
                    }
                }
                else {
                    sb.append(char1);
                    n = 0;
                }
            }
        }
        if (sb.length() > 0) {
            while (sb.charAt() == ' ' && length != sb.length() - 1) {
                sb.setLength();
            }
        }
        return sb.toString();
    }
    
    private static boolean isHexDigit(final char c) {
        return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
    }
    
    private static int convertHex(final char c) {
        if ('0' <= c && c <= '9') {
            return c - '0';
        }
        if ('a' <= c && c <= 'f') {
            return c - 'a' + 10;
        }
        return c - 'A' + 10;
    }
    
    public static RDN[] rDNsFromString(final String s, final X500NameStyle x500NameStyle) {
        final X500NameTokenizer x500NameTokenizer = new X500NameTokenizer(s);
        final X500NameBuilder x500NameBuilder = new X500NameBuilder(x500NameStyle);
        addRDNs(x500NameStyle, x500NameBuilder, x500NameTokenizer);
        return x500NameBuilder.build().getRDNs();
    }
    
    private static void addRDNs(final X500NameStyle x500NameStyle, final X500NameBuilder x500NameBuilder, final X500NameTokenizer x500NameTokenizer) {
        String nextToken;
        while ((nextToken = x500NameTokenizer.nextToken()) != null) {
            if (nextToken.indexOf(43) >= 0) {
                addMultiValuedRDN(x500NameStyle, x500NameBuilder, new X500NameTokenizer(nextToken, '+'));
            }
            else {
                addRDN(x500NameStyle, x500NameBuilder, nextToken);
            }
        }
    }
    
    private static void addMultiValuedRDN(final X500NameStyle x500NameStyle, final X500NameBuilder x500NameBuilder, final X500NameTokenizer x500NameTokenizer) {
        String s = x500NameTokenizer.nextToken();
        if (s == null) {
            throw new IllegalArgumentException("badly formatted directory string");
        }
        if (!x500NameTokenizer.hasMoreTokens()) {
            addRDN(x500NameStyle, x500NameBuilder, s);
            return;
        }
        final Vector vector = new Vector();
        final Vector vector2 = new Vector();
        do {
            collectAttributeTypeAndValue(x500NameStyle, vector, vector2, s);
            s = x500NameTokenizer.nextToken();
        } while (s != null);
        x500NameBuilder.addMultiValuedRDN(toOIDArray(vector), toValueArray(vector2));
    }
    
    private static void addRDN(final X500NameStyle x500NameStyle, final X500NameBuilder x500NameBuilder, final String s) {
        final X500NameTokenizer x500NameTokenizer = new X500NameTokenizer(s, '=');
        x500NameBuilder.addRDN(x500NameStyle.attrNameToOID(nextToken(x500NameTokenizer, true).trim()), unescape(nextToken(x500NameTokenizer, false)));
    }
    
    private static void collectAttributeTypeAndValue(final X500NameStyle x500NameStyle, final Vector vector, final Vector vector2, final String s) {
        final X500NameTokenizer x500NameTokenizer = new X500NameTokenizer(s, '=');
        final String nextToken = nextToken(x500NameTokenizer, true);
        final String nextToken2 = nextToken(x500NameTokenizer, false);
        final ASN1ObjectIdentifier attrNameToOID = x500NameStyle.attrNameToOID(nextToken.trim());
        final String unescape = unescape(nextToken2);
        vector.addElement(attrNameToOID);
        vector2.addElement(unescape);
    }
    
    private static String nextToken(final X500NameTokenizer x500NameTokenizer, final boolean b) {
        final String nextToken = x500NameTokenizer.nextToken();
        if (nextToken == null || x500NameTokenizer.hasMoreTokens() != b) {
            throw new IllegalArgumentException("badly formatted directory string");
        }
        return nextToken;
    }
    
    private static String[] toValueArray(final Vector vector) {
        final String[] array = new String[vector.size()];
        for (int i = 0; i != array.length; ++i) {
            array[i] = (String)vector.elementAt(i);
        }
        return array;
    }
    
    private static ASN1ObjectIdentifier[] toOIDArray(final Vector vector) {
        final ASN1ObjectIdentifier[] array = new ASN1ObjectIdentifier[vector.size()];
        for (int i = 0; i != array.length; ++i) {
            array[i] = (ASN1ObjectIdentifier)vector.elementAt(i);
        }
        return array;
    }
    
    public static String[] findAttrNamesForOID(final ASN1ObjectIdentifier asn1ObjectIdentifier, final Hashtable hashtable) {
        int n = 0;
        final Enumeration elements = hashtable.elements();
        while (elements.hasMoreElements()) {
            if (asn1ObjectIdentifier.equals(elements.nextElement())) {
                ++n;
            }
        }
        final String[] array = new String[n];
        int n2 = 0;
        final Enumeration keys = hashtable.keys();
        while (keys.hasMoreElements()) {
            final String key = (String)keys.nextElement();
            if (asn1ObjectIdentifier.equals(hashtable.get(key))) {
                array[n2++] = key;
            }
        }
        return array;
    }
    
    public static ASN1ObjectIdentifier decodeAttrName(final String str, final Hashtable hashtable) {
        if (str.regionMatches(true, 0, "OID.", 0, 4)) {
            return new ASN1ObjectIdentifier(str.substring(4));
        }
        final ASN1ObjectIdentifier tryFromID = ASN1ObjectIdentifier.tryFromID(str);
        if (tryFromID != null) {
            return tryFromID;
        }
        final ASN1ObjectIdentifier asn1ObjectIdentifier = hashtable.get(Strings.toLowerCase(str));
        if (asn1ObjectIdentifier != null) {
            return asn1ObjectIdentifier;
        }
        throw new IllegalArgumentException("Unknown object id - " + str + " - passed to distinguished name");
    }
    
    public static ASN1Encodable valueFromHexString(final String s, final int n) throws IOException {
        final byte[] array = new byte[(s.length() - n) / 2];
        for (int i = 0; i != array.length; ++i) {
            array[i] = (byte)(convertHex(s.charAt(i * 2 + n)) << 4 | convertHex(s.charAt(i * 2 + n + 1)));
        }
        return ASN1Primitive.fromByteArray(array);
    }
    
    public static void appendRDN(final StringBuilder sb, final RDN rdn, final Hashtable hashtable) {
        if (rdn.isMultiValued()) {
            final AttributeTypeAndValue[] typesAndValues = rdn.getTypesAndValues();
            int n = 1;
            for (int i = 0; i != typesAndValues.length; ++i) {
                if (n != 0) {
                    n = 0;
                }
                else {
                    sb.append('+');
                }
                appendTypeAndValue(sb, typesAndValues[i], hashtable);
            }
        }
        else if (rdn.getFirst() != null) {
            appendTypeAndValue(sb, rdn.getFirst(), hashtable);
        }
    }
    
    public static void appendRDN(final StringBuffer sb, final RDN rdn, final Hashtable hashtable) {
        if (rdn.isMultiValued()) {
            final AttributeTypeAndValue[] typesAndValues = rdn.getTypesAndValues();
            int n = 1;
            for (int i = 0; i != typesAndValues.length; ++i) {
                if (n != 0) {
                    n = 0;
                }
                else {
                    sb.append('+');
                }
                appendTypeAndValue(sb, typesAndValues[i], hashtable);
            }
        }
        else if (rdn.getFirst() != null) {
            appendTypeAndValue(sb, rdn.getFirst(), hashtable);
        }
    }
    
    public static void appendTypeAndValue(final StringBuilder sb, final AttributeTypeAndValue attributeTypeAndValue, final Hashtable hashtable) {
        final String str = hashtable.get(attributeTypeAndValue.getType());
        if (str != null) {
            sb.append(str);
        }
        else {
            sb.append(attributeTypeAndValue.getType().getId());
        }
        sb.append('=');
        sb.append(valueToString(attributeTypeAndValue.getValue()));
    }
    
    public static void appendTypeAndValue(final StringBuffer sb, final AttributeTypeAndValue attributeTypeAndValue, final Hashtable hashtable) {
        final String str = hashtable.get(attributeTypeAndValue.getType());
        if (str != null) {
            sb.append(str);
        }
        else {
            sb.append(attributeTypeAndValue.getType().getId());
        }
        sb.append('=');
        sb.append(valueToString(attributeTypeAndValue.getValue()));
    }
    
    public static String valueToString(final ASN1Encodable asn1Encodable) {
        final StringBuilder sb = new StringBuilder();
        if (asn1Encodable instanceof ASN1String && !(asn1Encodable instanceof ASN1UniversalString)) {
            final String string = ((ASN1String)asn1Encodable).getString();
            if (string.length() > 0 && string.charAt(0) == '#') {
                sb.append('\\');
            }
            sb.append(string);
        }
        else {
            try {
                sb.append('#');
                sb.append(Hex.toHexString(asn1Encodable.toASN1Primitive().getEncoded("DER")));
            }
            catch (final IOException ex) {
                throw new IllegalArgumentException("Other value has no encoded form");
            }
        }
        int length = sb.length();
        int i = 0;
        if (sb.length() >= 2 && sb.charAt() == '\\' && sb.charAt() == '#') {
            i += 2;
        }
        while (i != length) {
            switch (sb.charAt()) {
                case '\"':
                case '+':
                case ',':
                case ';':
                case '<':
                case '=':
                case '>':
                case '\\': {
                    sb.insert(i, "\\");
                    i += 2;
                    ++length;
                    continue;
                }
                default: {
                    ++i;
                    continue;
                }
            }
        }
        int offset = 0;
        if (sb.length() > 0) {
            while (sb.length() > offset && sb.charAt() == ' ') {
                sb.insert(offset, "\\");
                offset += 2;
            }
        }
        for (int offset2 = sb.length() - 1; offset2 >= offset && sb.charAt() == ' '; --offset2) {
            sb.insert(offset2, '\\');
        }
        return sb.toString();
    }
    
    public static String canonicalize(String s) {
        if (s.length() > 0 && s.charAt(0) == '#') {
            final ASN1Primitive decodeObject = decodeObject(s);
            if (decodeObject instanceof ASN1String) {
                s = ((ASN1String)decodeObject).getString();
            }
        }
        s = Strings.toLowerCase(s);
        final int length = s.length();
        if (length < 2) {
            return s;
        }
        int n;
        int n2;
        for (n = 0, n2 = length - 1; n < n2 && s.charAt(n) == '\\' && s.charAt(n + 1) == ' '; n += 2) {}
        int index;
        for (index = n2; index > n + 1 && s.charAt(index - 1) == '\\' && s.charAt(index) == ' '; index -= 2) {}
        if (n > 0 || index < n2) {
            s = s.substring(n, index + 1);
        }
        return stripInternalSpaces(s);
    }
    
    public static String canonicalString(final ASN1Encodable asn1Encodable) {
        return canonicalize(valueToString(asn1Encodable));
    }
    
    private static ASN1Primitive decodeObject(final String s) {
        try {
            return ASN1Primitive.fromByteArray(Hex.decodeStrict(s, 1, s.length() - 1));
        }
        catch (final IOException obj) {
            throw new IllegalStateException("unknown encoding in name: " + obj);
        }
    }
    
    public static String stripInternalSpaces(final String s) {
        if (s.indexOf("  ") < 0) {
            return s;
        }
        final StringBuilder sb = new StringBuilder();
        char char1 = s.charAt(0);
        sb.append(char1);
        for (int i = 1; i < s.length(); ++i) {
            final char char2 = s.charAt(i);
            if (char1 != ' ' || char2 != ' ') {
                sb.append(char2);
                char1 = char2;
            }
        }
        return sb.toString();
    }
    
    public static boolean rDNAreEqual(final RDN rdn, final RDN rdn2) {
        if (rdn.size() != rdn2.size()) {
            return false;
        }
        final AttributeTypeAndValue[] typesAndValues = rdn.getTypesAndValues();
        final AttributeTypeAndValue[] typesAndValues2 = rdn2.getTypesAndValues();
        if (typesAndValues.length != typesAndValues2.length) {
            return false;
        }
        for (int i = 0; i != typesAndValues.length; ++i) {
            if (!atvAreEqual(typesAndValues[i], typesAndValues2[i])) {
                return false;
            }
        }
        return true;
    }
    
    private static boolean atvAreEqual(final AttributeTypeAndValue attributeTypeAndValue, final AttributeTypeAndValue attributeTypeAndValue2) {
        return attributeTypeAndValue == attributeTypeAndValue2 || (null != attributeTypeAndValue && null != attributeTypeAndValue2 && attributeTypeAndValue.getType().equals(attributeTypeAndValue2.getType()) && canonicalString(attributeTypeAndValue.getValue()).equals(canonicalString(attributeTypeAndValue2.getValue())));
    }
}
