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

package io.netty.handler.codec.http3;

import io.netty.handler.codec.quic.QuicCodecBuilder;
import io.netty.handler.codec.quic.QuicClientCodecBuilder;
import io.netty.handler.codec.quic.QuicServerCodecBuilder;
import io.netty.handler.codec.quic.QuicStreamChannelBootstrap;
import io.netty.handler.codec.quic.QuicStreamType;
import io.netty.util.concurrent.Future;
import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.quic.QuicChannel;
import org.jetbrains.annotations.Nullable;
import io.netty.channel.Channel;
import io.netty.handler.codec.quic.QuicStreamChannel;
import io.netty.util.AttributeKey;

public final class Http3
{
    private static final String[] H3_PROTOS;
    private static final AttributeKey<QuicStreamChannel> HTTP3_CONTROL_STREAM_KEY;
    private static final AttributeKey<QpackAttributes> QPACK_ATTRIBUTES_KEY;
    public static final int MIN_INITIAL_MAX_STREAMS_UNIDIRECTIONAL = 3;
    public static final int MIN_INITIAL_MAX_STREAM_DATA_UNIDIRECTIONAL = 1024;
    
    private Http3() {
    }
    
    @Nullable
    public static QuicStreamChannel getLocalControlStream(final Channel channel) {
        return channel.attr(Http3.HTTP3_CONTROL_STREAM_KEY).get();
    }
    
    static long maxPushIdReceived(final QuicChannel channel) {
        final Http3ConnectionHandler connectionHandler = Http3CodecUtils.getConnectionHandlerOrClose(channel);
        if (connectionHandler == null) {
            throw new IllegalStateException("Connection handler not found.");
        }
        return connectionHandler.localControlStreamHandler.maxPushIdReceived();
    }
    
    static void setLocalControlStream(final Channel channel, final QuicStreamChannel controlStreamChannel) {
        channel.attr(Http3.HTTP3_CONTROL_STREAM_KEY).set(controlStreamChannel);
    }
    
    @Nullable
    static QpackAttributes getQpackAttributes(final Channel channel) {
        return channel.attr(Http3.QPACK_ATTRIBUTES_KEY).get();
    }
    
    static void setQpackAttributes(final Channel channel, final QpackAttributes attributes) {
        channel.attr(Http3.QPACK_ATTRIBUTES_KEY).set(attributes);
    }
    
    public static Future<QuicStreamChannel> newRequestStream(final QuicChannel channel, final ChannelHandler handler) {
        return channel.createStream(QuicStreamType.BIDIRECTIONAL, requestStreamInitializer(handler));
    }
    
    public static QuicStreamChannelBootstrap newRequestStreamBootstrap(final QuicChannel channel, final ChannelHandler handler) {
        return channel.newStreamBootstrap().handler(requestStreamInitializer(handler)).type(QuicStreamType.BIDIRECTIONAL);
    }
    
    public static String[] supportedApplicationProtocols() {
        return Http3.H3_PROTOS.clone();
    }
    
    public static QuicServerCodecBuilder newQuicServerCodecBuilder() {
        return configure(new QuicServerCodecBuilder());
    }
    
    public static QuicClientCodecBuilder newQuicClientCodecBuilder() {
        return configure(new QuicClientCodecBuilder());
    }
    
    private static <T extends QuicCodecBuilder<T>> T configure(final T builder) {
        return ((QuicCodecBuilder<QuicCodecBuilder<T>>)builder).initialMaxStreamsUnidirectional(3L).initialMaxStreamDataUnidirectional(1024L);
    }
    
    private static Http3RequestStreamInitializer requestStreamInitializer(final ChannelHandler handler) {
        if (handler instanceof Http3RequestStreamInitializer) {
            return (Http3RequestStreamInitializer)handler;
        }
        return new Http3RequestStreamInitializer() {
            @Override
            protected void initRequestStream(final QuicStreamChannel ch) {
                ch.pipeline().addLast(handler);
            }
        };
    }
    
    static {
        H3_PROTOS = new String[] { "h3-29", "h3-30", "h3-31", "h3-32", "h3" };
        HTTP3_CONTROL_STREAM_KEY = AttributeKey.valueOf(Http3.class, "HTTP3ControlStream");
        QPACK_ATTRIBUTES_KEY = AttributeKey.valueOf(Http3.class, "QpackAttributes");
    }
}
