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

package io.netty.handler.codec.quic;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.concurrent.Promise;
import io.netty.util.concurrent.Future;
import org.jetbrains.annotations.Nullable;
import io.netty.util.internal.ObjectUtil;
import java.util.HashMap;
import java.util.LinkedHashMap;
import io.netty.channel.ChannelHandler;
import io.netty.util.AttributeKey;
import io.netty.channel.ChannelOption;
import java.util.Map;
import io.netty.util.internal.logging.InternalLogger;

public final class QuicStreamChannelBootstrap
{
    private static final InternalLogger logger;
    private final QuicChannel parent;
    private final Map<ChannelOption<?>, Object> options;
    private final Map<AttributeKey<?>, Object> attrs;
    private ChannelHandler handler;
    private QuicStreamType type;
    
    QuicStreamChannelBootstrap(final QuicChannel parent) {
        this.options = new LinkedHashMap<ChannelOption<?>, Object>();
        this.attrs = new HashMap<AttributeKey<?>, Object>();
        this.type = QuicStreamType.BIDIRECTIONAL;
        this.parent = ObjectUtil.checkNotNull(parent, "parent");
    }
    
    public <T> QuicStreamChannelBootstrap option(final ChannelOption<T> option, @Nullable final T value) {
        Quic.updateOptions(this.options, option, value);
        return this;
    }
    
    public <T> QuicStreamChannelBootstrap attr(final AttributeKey<T> key, @Nullable final T value) {
        Quic.updateAttributes(this.attrs, key, value);
        return this;
    }
    
    public QuicStreamChannelBootstrap handler(final ChannelHandler streamHandler) {
        this.handler = ObjectUtil.checkNotNull(streamHandler, "streamHandler");
        return this;
    }
    
    public QuicStreamChannelBootstrap type(final QuicStreamType type) {
        this.type = ObjectUtil.checkNotNull(type, "type");
        return this;
    }
    
    public Future<QuicStreamChannel> create() {
        return this.create(this.parent.eventLoop().newPromise());
    }
    
    public Future<QuicStreamChannel> create(final Promise<QuicStreamChannel> promise) {
        if (this.handler == null) {
            throw new IllegalStateException("streamHandler not set");
        }
        return this.parent.createStream(this.type, new QuicStreamChannelBootstrapHandler(this.handler, Quic.toOptionsArray(this.options), Quic.toAttributesArray(this.attrs)), promise);
    }
    
    static {
        logger = InternalLoggerFactory.getInstance(QuicStreamChannelBootstrap.class);
    }
    
    private static final class QuicStreamChannelBootstrapHandler extends ChannelInitializer<QuicStreamChannel>
    {
        private final ChannelHandler streamHandler;
        private final Map.Entry<ChannelOption<?>, Object>[] streamOptions;
        private final Map.Entry<AttributeKey<?>, Object>[] streamAttrs;
        
        QuicStreamChannelBootstrapHandler(final ChannelHandler streamHandler, final Map.Entry<ChannelOption<?>, Object>[] streamOptions, final Map.Entry<AttributeKey<?>, Object>[] streamAttrs) {
            this.streamHandler = streamHandler;
            this.streamOptions = streamOptions;
            this.streamAttrs = streamAttrs;
        }
        
        @Override
        protected void initChannel(final QuicStreamChannel ch) {
            Quic.setupChannel(ch, this.streamOptions, this.streamAttrs, this.streamHandler, QuicStreamChannelBootstrap.logger);
        }
    }
}
