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

package org.bouncycastle.oer;

import org.bouncycastle.asn1.ASN1Absent;
import org.bouncycastle.asn1.ASN1Primitive;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;

public class OEROptional extends ASN1Object
{
    public static final OEROptional ABSENT;
    private final boolean defined;
    private final ASN1Encodable value;
    
    private OEROptional(final boolean defined, final ASN1Encodable value) {
        this.defined = defined;
        this.value = value;
    }
    
    public static OEROptional getInstance(final Object o) {
        if (o instanceof OEROptional) {
            return (OEROptional)o;
        }
        if (o instanceof ASN1Encodable) {
            return new OEROptional(true, (ASN1Encodable)o);
        }
        return OEROptional.ABSENT;
    }
    
    public static <T> T getValue(final Class<T> clazz, final Object o) {
        final OEROptional instance = getInstance(o);
        if (!instance.defined) {
            return null;
        }
        return instance.getObject(clazz);
    }
    
    public <T> T getObject(final Class<T> clazz) {
        if (!this.defined) {
            return null;
        }
        if (this.value.getClass().isInstance(clazz)) {
            return clazz.cast(this.value);
        }
        return AccessController.doPrivileged((PrivilegedAction<T>)new PrivilegedAction<T>() {
            @Override
            public T run() {
                try {
                    return clazz.cast(clazz.getMethod("getInstance", Object.class).invoke(null, OEROptional.this.value));
                }
                catch (final Exception cause) {
                    throw new IllegalStateException("could not invoke getInstance on type " + cause.getMessage(), cause);
                }
            }
        });
    }
    
    public ASN1Encodable get() {
        if (!this.defined) {
            return OEROptional.ABSENT;
        }
        return this.value;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        if (!this.defined) {
            return ASN1Absent.INSTANCE;
        }
        return this.get().toASN1Primitive();
    }
    
    public boolean isDefined() {
        return this.defined;
    }
    
    @Override
    public String toString() {
        if (this.defined) {
            return "OPTIONAL(" + this.value + ")";
        }
        return "ABSENT";
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        if (!super.equals(o)) {
            return false;
        }
        final OEROptional oerOptional = (OEROptional)o;
        return this.defined == oerOptional.defined && ((this.value != null) ? this.value.equals(oerOptional.value) : (oerOptional.value == null));
    }
    
    @Override
    public int hashCode() {
        return 31 * (31 * super.hashCode() + (this.defined ? 1 : 0)) + ((this.value != null) ? this.value.hashCode() : 0);
    }
    
    static {
        ABSENT = new OEROptional(false, null);
    }
}
