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

package com.hypixel.hytale.protocol.io.netty;

import io.netty.channel.ChannelFuture;
import io.netty.buffer.ByteBuf;
import java.nio.charset.StandardCharsets;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.quic.QuicChannel;
import io.netty.handler.codec.quic.QuicTransportError;
import javax.annotation.Nonnull;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import java.time.Duration;
import io.netty.util.AttributeKey;

public final class ProtocolUtil
{
    public static final AttributeKey<Duration> PACKET_TIMEOUT_KEY;
    public static final int APPLICATION_NO_ERROR = 0;
    public static final int APPLICATION_RATE_LIMITED = 1;
    public static final int APPLICATION_AUTH_FAILED = 2;
    public static final int APPLICATION_INVALID_VERSION = 3;
    public static final int APPLICATION_TIMEOUT = 4;
    public static final int APPLICATION_CLIENT_OUTDATED = 5;
    public static final int APPLICATION_SERVER_OUTDATED = 6;
    public static final ChannelFutureListener CLOSE_ON_COMPLETE;
    
    private ProtocolUtil() {
    }
    
    public static void closeConnection(@Nonnull final Channel channel) {
        closeConnection(channel, QuicTransportError.PROTOCOL_VIOLATION);
    }
    
    public static void closeConnection(@Nonnull final Channel channel, @Nonnull final QuicTransportError error) {
        final int errorCode = (int)error.code();
        if (channel instanceof final QuicChannel quicChannel) {
            quicChannel.close(false, errorCode, Unpooled.EMPTY_BUFFER);
            return;
        }
        final Channel parent = channel.parent();
        if (parent instanceof final QuicChannel quicChannel2) {
            quicChannel2.close(false, errorCode, Unpooled.EMPTY_BUFFER);
        }
        else {
            channel.close();
        }
    }
    
    public static void closeApplicationConnection(@Nonnull final Channel channel) {
        closeApplicationConnection(channel, 0);
    }
    
    public static void closeApplicationConnection(@Nonnull final Channel channel, final int errorCode) {
        if (channel instanceof final QuicChannel quicChannel) {
            quicChannel.close(true, errorCode, Unpooled.EMPTY_BUFFER);
            return;
        }
        final Channel parent = channel.parent();
        if (parent instanceof final QuicChannel quicChannel2) {
            quicChannel2.close(true, errorCode, Unpooled.EMPTY_BUFFER);
        }
        else {
            channel.close();
        }
    }
    
    public static void closeApplicationConnection(@Nonnull final Channel channel, final int errorCode, @Nonnull final String reason) {
        final ByteBuf reasonBuf = Unpooled.copiedBuffer(reason, StandardCharsets.UTF_8);
        if (channel instanceof final QuicChannel quicChannel) {
            quicChannel.close(true, errorCode, reasonBuf);
            return;
        }
        final Channel parent = channel.parent();
        if (parent instanceof final QuicChannel quicChannel2) {
            quicChannel2.close(true, errorCode, reasonBuf);
        }
        else {
            reasonBuf.release();
            channel.close();
        }
    }
    
    private static void closeApplicationOnComplete(final ChannelFuture future) {
        closeApplicationConnection(future.channel());
    }
    
    static {
        PACKET_TIMEOUT_KEY = AttributeKey.newInstance("PACKET_TIMEOUT");
        CLOSE_ON_COMPLETE = ProtocolUtil::closeApplicationOnComplete;
    }
}
