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

package org.bson.internal;

import org.bson.codecs.OverridableUuidRepresentationCodec;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.Codec;
import org.bson.assertions.Assertions;
import org.bson.UuidRepresentation;
import org.bson.codecs.configuration.CodecProvider;

public class OverridableUuidRepresentationCodecRegistry implements CycleDetectingCodecRegistry
{
    private final CodecProvider wrapped;
    private final CodecCache codecCache;
    private final UuidRepresentation uuidRepresentation;
    
    OverridableUuidRepresentationCodecRegistry(final CodecProvider wrapped, final UuidRepresentation uuidRepresentation) {
        this.codecCache = new CodecCache();
        this.uuidRepresentation = Assertions.notNull("uuidRepresentation", uuidRepresentation);
        this.wrapped = Assertions.notNull("wrapped", wrapped);
    }
    
    public UuidRepresentation getUuidRepresentation() {
        return this.uuidRepresentation;
    }
    
    public CodecProvider getWrapped() {
        return this.wrapped;
    }
    
    @Override
    public <T> Codec<T> get(final Class<T> clazz) {
        return this.get(new ChildCodecRegistry<T>(this, clazz));
    }
    
    @Override
    public <T> Codec<T> get(final Class<T> clazz, final CodecRegistry registry) {
        final Codec<T> codec = this.wrapped.get(clazz, registry);
        if (codec instanceof OverridableUuidRepresentationCodec) {
            return ((OverridableUuidRepresentationCodec)codec).withUuidRepresentation(this.uuidRepresentation);
        }
        return codec;
    }
    
    @Override
    public <T> Codec<T> get(final ChildCodecRegistry<T> context) {
        if (!this.codecCache.containsKey(context.getCodecClass())) {
            Codec<T> codec = this.wrapped.get(context.getCodecClass(), context);
            if (codec instanceof OverridableUuidRepresentationCodec) {
                codec = ((OverridableUuidRepresentationCodec)codec).withUuidRepresentation(this.uuidRepresentation);
            }
            this.codecCache.put(context.getCodecClass(), codec);
        }
        return this.codecCache.getOrThrow(context.getCodecClass());
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || this.getClass() != o.getClass()) {
            return false;
        }
        final OverridableUuidRepresentationCodecRegistry that = (OverridableUuidRepresentationCodecRegistry)o;
        return this.wrapped.equals(that.wrapped) && this.uuidRepresentation == that.uuidRepresentation;
    }
    
    @Override
    public int hashCode() {
        int result = this.wrapped.hashCode();
        result = 31 * result + this.uuidRepresentation.hashCode();
        return result;
    }
}
