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

package org.bouncycastle.asn1.util;

import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1External;
import org.bouncycastle.asn1.ASN1ObjectDescriptor;
import org.bouncycastle.asn1.ASN1Enumerated;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1UTCTime;
import org.bouncycastle.asn1.ASN1VideotexString;
import org.bouncycastle.asn1.ASN1GraphicString;
import org.bouncycastle.asn1.ASN1T61String;
import org.bouncycastle.asn1.ASN1BMPString;
import org.bouncycastle.asn1.ASN1VisibleString;
import org.bouncycastle.asn1.ASN1PrintableString;
import org.bouncycastle.asn1.ASN1NumericString;
import org.bouncycastle.asn1.ASN1UTF8String;
import org.bouncycastle.asn1.ASN1IA5String;
import org.bouncycastle.asn1.DLBitString;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.BEROctetString;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1RelativeOID;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Util;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.BERTaggedObject;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.BERSet;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.util.Strings;
import org.bouncycastle.asn1.ASN1Primitive;

public class ASN1Dump
{
    private static final String TAB = "    ";
    private static final int SAMPLE_SIZE = 32;
    
    static void _dumpAsString(final String str, final boolean b, final ASN1Primitive asn1Primitive, final StringBuilder sb) {
        final String lineSeparator = Strings.lineSeparator();
        sb.append(str);
        if (asn1Primitive instanceof ASN1Null) {
            sb.append("NULL");
            sb.append(lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1Sequence) {
            if (asn1Primitive instanceof BERSequence) {
                sb.append("BER Sequence");
            }
            else if (asn1Primitive instanceof DERSequence) {
                sb.append("DER Sequence");
            }
            else {
                sb.append("Sequence");
            }
            sb.append(lineSeparator);
            final ASN1Sequence asn1Sequence = (ASN1Sequence)asn1Primitive;
            final String string = str + "    ";
            for (int i = 0; i < asn1Sequence.size(); ++i) {
                _dumpAsString(string, b, asn1Sequence.getObjectAt(i).toASN1Primitive(), sb);
            }
        }
        else if (asn1Primitive instanceof ASN1Set) {
            if (asn1Primitive instanceof BERSet) {
                sb.append("BER Set");
            }
            else if (asn1Primitive instanceof DERSet) {
                sb.append("DER Set");
            }
            else {
                sb.append("Set");
            }
            sb.append(lineSeparator);
            final ASN1Set set = (ASN1Set)asn1Primitive;
            final String string2 = str + "    ";
            for (int j = 0; j < set.size(); ++j) {
                _dumpAsString(string2, b, set.getObjectAt(j).toASN1Primitive(), sb);
            }
        }
        else if (asn1Primitive instanceof ASN1TaggedObject) {
            if (asn1Primitive instanceof BERTaggedObject) {
                sb.append("BER Tagged ");
            }
            else if (asn1Primitive instanceof DERTaggedObject) {
                sb.append("DER Tagged ");
            }
            else {
                sb.append("Tagged ");
            }
            final ASN1TaggedObject asn1TaggedObject = (ASN1TaggedObject)asn1Primitive;
            sb.append(ASN1Util.getTagText(asn1TaggedObject));
            if (!asn1TaggedObject.isExplicit()) {
                sb.append(" IMPLICIT");
            }
            sb.append(lineSeparator);
            _dumpAsString(str + "    ", b, asn1TaggedObject.getBaseObject().toASN1Primitive(), sb);
        }
        else if (asn1Primitive instanceof ASN1ObjectIdentifier) {
            sb.append("ObjectIdentifier(" + ((ASN1ObjectIdentifier)asn1Primitive).getId() + ")" + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1RelativeOID) {
            sb.append("RelativeOID(" + ((ASN1RelativeOID)asn1Primitive).getId() + ")" + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1Boolean) {
            sb.append("Boolean(" + ((ASN1Boolean)asn1Primitive).isTrue() + ")" + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1Integer) {
            sb.append("Integer(" + ((ASN1Integer)asn1Primitive).getValue() + ")" + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1OctetString) {
            final ASN1OctetString asn1OctetString = (ASN1OctetString)asn1Primitive;
            if (asn1Primitive instanceof BEROctetString) {
                sb.append("BER Constructed Octet String[");
            }
            else {
                sb.append("DER Octet String[");
            }
            sb.append(asn1OctetString.getOctetsLength() + "]" + lineSeparator);
            if (b) {
                dumpBinaryDataAsString(sb, str, asn1OctetString.getOctets());
            }
        }
        else if (asn1Primitive instanceof ASN1BitString) {
            final ASN1BitString asn1BitString = (ASN1BitString)asn1Primitive;
            if (asn1BitString instanceof DERBitString) {
                sb.append("DER Bit String[");
            }
            else if (asn1BitString instanceof DLBitString) {
                sb.append("DL Bit String[");
            }
            else {
                sb.append("BER Bit String[");
            }
            sb.append(asn1BitString.getBytesLength() + ", " + asn1BitString.getPadBits() + "]" + lineSeparator);
            if (b) {
                dumpBinaryDataAsString(sb, str, asn1BitString.getBytes());
            }
        }
        else if (asn1Primitive instanceof ASN1IA5String) {
            sb.append("IA5String(" + ((ASN1IA5String)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1UTF8String) {
            sb.append("UTF8String(" + ((ASN1UTF8String)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1NumericString) {
            sb.append("NumericString(" + ((ASN1NumericString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1PrintableString) {
            sb.append("PrintableString(" + ((ASN1PrintableString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1VisibleString) {
            sb.append("VisibleString(" + ((ASN1VisibleString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1BMPString) {
            sb.append("BMPString(" + ((ASN1BMPString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1T61String) {
            sb.append("T61String(" + ((ASN1T61String)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1GraphicString) {
            sb.append("GraphicString(" + ((ASN1GraphicString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1VideotexString) {
            sb.append("VideotexString(" + ((ASN1VideotexString)asn1Primitive).getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1UTCTime) {
            sb.append("UTCTime(" + ((ASN1UTCTime)asn1Primitive).getTime() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1GeneralizedTime) {
            sb.append("GeneralizedTime(" + ((ASN1GeneralizedTime)asn1Primitive).getTime() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1Enumerated) {
            sb.append("DER Enumerated(" + ((ASN1Enumerated)asn1Primitive).getValue() + ")" + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1ObjectDescriptor) {
            sb.append("ObjectDescriptor(" + ((ASN1ObjectDescriptor)asn1Primitive).getBaseGraphicString().getString() + ") " + lineSeparator);
        }
        else if (asn1Primitive instanceof ASN1External) {
            final ASN1External asn1External = (ASN1External)asn1Primitive;
            sb.append("External " + lineSeparator);
            final String string3 = str + "    ";
            if (asn1External.getDirectReference() != null) {
                sb.append(string3 + "Direct Reference: " + asn1External.getDirectReference().getId() + lineSeparator);
            }
            if (asn1External.getIndirectReference() != null) {
                sb.append(string3 + "Indirect Reference: " + asn1External.getIndirectReference().toString() + lineSeparator);
            }
            if (asn1External.getDataValueDescriptor() != null) {
                _dumpAsString(string3, b, asn1External.getDataValueDescriptor(), sb);
            }
            sb.append(string3 + "Encoding: " + asn1External.getEncoding() + lineSeparator);
            _dumpAsString(string3, b, asn1External.getExternalContent(), sb);
        }
        else {
            sb.append(asn1Primitive.toString() + lineSeparator);
        }
    }
    
    public static String dumpAsString(final Object o) {
        return dumpAsString(o, false);
    }
    
    public static String dumpAsString(final Object o, final boolean b) {
        ASN1Primitive asn1Primitive;
        if (o instanceof ASN1Primitive) {
            asn1Primitive = (ASN1Primitive)o;
        }
        else {
            if (!(o instanceof ASN1Encodable)) {
                return "unknown object type " + o.toString();
            }
            asn1Primitive = ((ASN1Encodable)o).toASN1Primitive();
        }
        final StringBuilder sb = new StringBuilder();
        _dumpAsString("", b, asn1Primitive, sb);
        return sb.toString();
    }
    
    private static void dumpBinaryDataAsString(final StringBuilder sb, String string, final byte[] array) {
        if (array.length < 1) {
            return;
        }
        final String lineSeparator = Strings.lineSeparator();
        string += "    ";
        for (int i = 0; i < array.length; i += 32) {
            final int min = Math.min(array.length - i, 32);
            sb.append(string);
            sb.append(Hex.toHexString(array, i, min));
            for (int j = min; j < 32; ++j) {
                sb.append("  ");
            }
            sb.append("    ");
            appendAscString(sb, array, i, min);
            sb.append(lineSeparator);
        }
    }
    
    private static void appendAscString(final StringBuilder sb, final byte[] array, final int n, final int n2) {
        for (int i = n; i != n + n2; ++i) {
            if (array[i] >= 32 && array[i] <= 126) {
                sb.append((char)array[i]);
            }
        }
    }
}
